【Linux】Linux项目自动化构建工具make makefile
文章目录
- 1. 背景
- 2.实例
- 3.原理
- 4.项目清理
- 5. 文件属性中的三个时间
- 6. Linux下第一个小程序——进度条
- 6.1 前置知识1:缓冲区
- 6.2前置知识2:回车换行
- 6.3进度条的实现
- 7 Linux下git的”三板斧“
1. 背景
- 一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率
- make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法
- make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建
2.实例
下面,我们使用一个例子来示范怎么使用make和makefile
这里分别是我们的C语言源文件和makefile的内容,然后我们使用make指令
可以看到,使用make指令之后,就执行了makefile的第一行,也就第一个依赖方法。当执行make clean时,执行了clean的内容。这样就完成了我们所需要的功能
下面,我们来详细分析一下上面范例中的各个代码的作用
3.原理
首先明确一点,make/makefile的存在是为了构建项目,构建项目需要依赖关系和依赖方法。举个例子,学生时代的我们都会问父母要钱,要钱的时候,我们会说“老爸,我没钱了,给我打钱”,这里前面半句话就是表明了依赖关系:我是你儿子,你是我爸爸,后面半句话就是表明了依赖方法:给我打钱。
所以,在makefile中需要写的就是依赖关系和依赖方法,然后使用make去通过依赖关系执行依赖方法,从而产生我们需要的文件或者指令。
make是如何工作的?
- make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
- 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“test_make”这个文件,并把这个文件作为最终的目标文件。
- 如果test_make文件不存在,或是test_make所依赖的后面的test_make.c文件的文件修改时间要比hello这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成hello这个文件。
- 如果test_make所依赖的test_make.c文件不存在,那么make会在当前文件中找目标为test_make.c文件的依赖性,如果找到则再根据那一个规则生成test_make.c文件。(这有点像一个堆栈的过程)
- 当然,你的.c文件和.h文件是存在的啦,于是make会生成 test_make.c 文件,然后再用 test_make.c 文件声明make的终极任务,也就是执行文件test_make了。
- 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
- 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
- make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦
知道了这些东西,那么我们如何着手去使用make构建项目呢?
makefile的编写
创建一个名为makefile或者Makefile的文件(只能是这两种可能,否则make识别不出来),在makefile中写入内容
建立依赖关系,谁依赖:于谁,例如上述的实例就是test_make依赖于test_make.c,所以在makefile的首行写
test_make:test_make.c,意思是test_make是由我们自己写的test_make.c编译得来的新起一行,必须以tab键开头(不能是四个空格),写编译的指令,例如上述的
gcc -o test_make test_make.c
makefile的使用
当我们写好makefile之后,直接使用
make 目标文件名/指令名,就可以达到使用make和makefile构建项目的目的,但是,我们上述的实例中直接使用了make指令,没有加上刚刚说的目标文件,也能够正常执行,达到效果,为什么呢?这是因为在makefile中被一个目标文件直接或者间接关联,那么他后面所定义的命令能够被自动执行。
4.项目清理
工程是需要被清理的
在上述的makefile中,我们同时设置了clean这个目标指令的,他的目的就是为了清除我们编译好的工程文件。

但是我们回到上述实例中,可以发现,多了一行内容,是我们不理解的东西,那么它是什么呢?
.PHONY:表示被该关键字修饰的对象是一个伪目标,这里我们引入了一个新的概念,叫做伪目标
什么是伪目标?
还是使用之前的那个test_make,我们发现,当该路径下没有目标文件的时候,我们能够正常的执行make指令,但是当我们想再次执行make指令的时候,发现出现了提示,没有办法正常执行make指令。反而,我们在执行make clean的时候,没有这种情况,能够连续执行任意次的make clean。这就是伪目标的作用。伪目标表示该目标是永远被执行的!!!
对于上述的情况,我们只需要再修改一下源文件test_make.c,就会发现make又可以正常执行一次了。这是因为,make会识别我们上一次编译之后,源文件是否已经被修改,如果没有被修改,就不需要再次执行编译操作,(这一点是很重要的,一个中大型的项目,编译所花的时间短则几十分钟,长则几个小时甚至十几个小时)。
那么make是怎么知道源文件有没有被修改的呢?
答案是比较时间,比较源文件和目标文件的内容修改时间
我们知道,是先有源文件,在有目标文件的,所以,我们只需要比较源文件和目标文件的内容修改时间,如果源文件的内容修改时间早于目标文件的修改时间,那就说明源文件在生成目标文件之后,没有被更改,所以就没有再次编译的必要,否则就需要再次编译。
5. 文件属性中的三个时间
上面我们讲到了文件的修改时间,在这里我们详细介绍一下文件的“三个时间”。
使用stat指令,我们可以看到文件的详细信息,其中就包括了文件的创建时间,修改时间与最后一次访问时间

对于modify和change的时间是容易理解的,但是access的时间改变规则有些不一样
因为对一个文件的访问,是很频繁的,如果每一次的访问,都要修改access时间的话,会导致系统的负荷太大,所以新的Linux内核就对access时间的修改规则做了修正,变成了根据一段时间内访问频率再去更新。
6. Linux下第一个小程序——进度条
6.1 前置知识1:缓冲区

对于这个测试,执行之后的结果是在屏幕上正常的打印hello world,然后停留一秒钟之后再提示输入下一个指令,但是我们将printf中的‘\n’去掉,然后再编译,执行得到的可执行,会发现屏幕中没有立刻显示hello world,而是再一秒钟后再显示的,这是因为每一行的内容会先放在缓冲区中,当执行回车换行也就是‘\n’之后,才会显示,否则就需要等当前进程结束之后再显示,所以为了让上述程序在没有‘\n’也能正常执行,我们需要使用fflush刷新缓冲区,即:

然后我们发现该程序可以正常执行输出然后再停顿了。
6.2前置知识2:回车换行
在刚刚,我们提到了回车换行的概念,但是,回车和换行是两个概念,回车表示的是回到当前行的开头位置,用\r表示,换行表示光标换到下一行的同一位置,但是到这里就会有疑问,我们键盘上的enter键,一般不就是叫做回车键嘛?我们注意一下早期的键盘上,回车键是什么样子的

用了一个向下和向左的箭头表示着这个键的作用是让光标去到下一行的开头。
那么如果不换行,只回车的话,会出现什么情况呢?
答案是会将屏幕上当前行的内容覆盖掉。
那么,利用这种特性,我们能够写出一个简易的倒计时程序

运行的结果是这样的:

这就是我们利用缓冲区和回车换行的特性写出来的简易倒计时。
6.3进度条的实现
有了上述的两个前置知识,我们就可以利用已知的知识写出进度条啦
接下来我们尝试一下多文件编程,首先定义一下头文件和主要的实现源文件,还有主函数文件,分别命名为process.h,process.c,main.c,然后对于一整个项目,我们要写一下makefile文件所以一共要创建四个文件
$ touch makefile process.c process.h main.c


各个部分代码如上,然后使用make编译,产生可执行文件ProcessOn,运行效果如下

7 Linux下git的”三板斧“
由于Linux是没有图形化界面的,所以我们在Windows下使用的“小乌龟”在这里就不能用了,所以我们要学一下git的命令行使用方式
1. git clone
首先,我们需要将已有的仓库拷贝到本地,所以就有了git clone指令,该指令后面跟我们需要拷贝的仓库的链接
2. git add
我们在本地写的代码需要添加到本地仓库,所以需要使用git add指令添加,git add指令后跟文件名,这里我们经常使用的是
git add .表示将所有新增文件全部添加3. git commit
对标Windows下使用小乌龟的过程,我们同样需要commit,我们在commit的同时,还需要附带本次上传的说明,
git commit -m "说明文字"4. git push
上传到本地仓库之后,我们还需要上传到线上的仓库,对标”小乌龟“,我们需要push,所以使用git push指令
注:默认每次上传的时候都要输入用户名和密码,这里可以配置成不需要输入,但是还是建议每次都手动输入点我配置免密码提交
5. git log
我们的每次上传都会被记录下来,成为日志,使用git log就可以查看提交日志
本节完。。。
相关文章:
【Linux】Linux项目自动化构建工具make makefile
文章目录1. 背景2.实例3.原理4.项目清理5. 文件属性中的三个时间6. Linux下第一个小程序——进度条6.1 前置知识1:缓冲区6.2前置知识2:回车换行6.3进度条的实现7 Linux下git的”三板斧“1. 背景 一个工程中的源文件不计其数,其按类型、功能、…...
华为OD机试题 - IPv4 地址转换成整数(JavaScript)| 含思路
华为OD机试题 最近更新的博客使用说明本篇题解: IPv4 地址转换成整数题目输入输出示例一输入输出说明示例一输入输出说明Code解题思路华为OD其它语言版本最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | …...
spring整合通用mapper
1.使用通用mapper可以更快速的进行数据库的增删查改操作,加入springboot的管理,常规的SQL都可以复用 2.整合 a)引入依赖 <dependencies><dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId>…...
一天什么时间发抖音浏览量高?5个抖音最佳发布时间段
抖音作为现在一款现象级的软件,已经不知不觉地影响着我们生活的方方面面。那抖音想要被更多人看到,就需要掐准哪些时间活跃数最多,今天就来和大家分享一下一天什么时间发抖音浏览量高,又该如何抓住最佳投放契机呢?一、一天什么时…...
华为OD机试题 - 关联子串(JavaScript)| 含思路
华为OD机试题 最近更新的博客使用说明本篇题解:关联子串题目输入输出示例一输入输出说明示例二输入输出说明Code解题思路华为OD其它语言版本最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典...
【代码随想录训练营】【Day33休息】【Day34】第八章|贪心算法|1005.K次取反后最大化的数组和|134. 加油站|135. 分发糖果
K 次取反后最大化的数组和 题目详细:LeetCode.1005 这道题比较简单,这里直接给出贪心策略: 局部最优解: 按照 负数 > 0 > 正数 的优先级次序,依次对nums中的较小数值进行取反因为负负得正,负值越小…...
<c++> const 常量限定符
文章目录什么是 const 常量限定符const 的初始化const 的默认作用域const 的引用例外情况const 与指针const指针的声明指向 const 的指针const指针指向 const 的 const指针什么是 const 常量限定符 Q:什么是 const 常量限定符? A:const名叫常…...
pytorch实现transformer模型
Transformer是一种强大的神经网络架构,可用于处理序列数据,例如自然语言处理任务。在PyTorch中,可以使用torch.nn.Transformer类轻松实现Transformer模型。 以下是一个简单的Transformer模型实现的示例代码,它将一个输入序列转换为…...
【懒加载数据 Objective-C语言】
一、咱们就开始进行懒加载 1.懒加载发现,每一个字典,是不是就是四个键值对组成的: 1)answer:String,中国合伙人, 2)icon:String,movie_zghhr, 3)title:String,创业励志电影, 4)options:Array,21 items 前三个都是String类型,最后是不是Array类型, 所…...
人脸网格/人脸3D重建 face_mesh(毕业设计+代码)
概述 Face Mesh是一个解决方案,可在移动设备上实时估计468个3D面部地标。它利用机器学习(ML)推断3D面部表面,只需要单个摄像头输入,无需专用深度传感器。利用轻量级模型架构以及整个管道中的GPU加速,该解决…...
JMeter 控制并发数
文章目录一、误区二、正确设置 JMeter 的并发数总结没用过 JMeter 的同学,可以先过一遍他的简单使用例子 https://blog.csdn.net/weixin_42132143/article/details/118875293?spm1001.2014.3001.5501 一、误区 在使用 JMeter 做压测时,大家都知道要这么…...
git常用命令汇总
Git 是一种分布式版本控制系统,它具有以下优点: 分布式:每个开发者都可以拥有自己的本地代码仓库,不需要连接到中央服务器,这样可以避免单点故障和网络延迟等问题。 非线性开发:Git 可以支持多个分支并行开…...
【2023】华为OD机试真题Java-题目0226-寻找相似单词
寻找相似单词 题目描述 给定一个可存储若干单词的字典,找出指定单词的所有相似单词,并且按照单词名称从小到大排序输出。单词仅包括字母,但可能大小写并存(大写不一定只出现在首字母)。 相似单词说明:给定一个单词X,如果通过任意交换单词中字母的位置得到不同的单词Y,…...
【项目管理】晋升为领导后,如何开展工作?
兵随将转,作为管理者,你可以不知道下属的短处,却不能不知道下属的长处。晋升为领导后,如何开展工作呢? 金九银十,此期间换工作的人不在少数。有几位朋友最近都换了公司,职位得到晋升,…...
JAVA开发(Spring Gateway 的原理和使用)
在springCloud的架构中,业务服务都是以微服务来划分的,每个服务可能都有自己的地址和端口。如果前端或者说是客户端直接去调用不同的微服务的话,就要配置不同的地址。其实这是一个解耦和去中心化出现的弊端。所以springCloud体系中࿰…...
踩坑:解决npm版本升级报错,无法安装node-sass的问题
npm版本由于经常更新,迁移前端项目时经常发现报错安装不上。 比如,项目经常使用的sass模块,可能迁移的时候就发现安装不了。 因为node-sass 编译器是通过 C 实现的。在 Node.js 中,采用 gyp 构建工具进行构建 C 代码,…...
xFormers安装使用
xFormers是一个模块化和可编程的Transformer建模库,可以加速图像的生成。 这种优化仅适用于nvidia gpus,它加快了图像生成,并降低了vram的使用量,而成本产生了非确定性的结果。 下载地址: https://github.com/faceb…...
React—— hooks(一)
🧁个人主页:个人主页 ✌支持我 :点赞👍收藏🌼关注🧡 文章目录⛳React Hooks💸useState(保存组件状态)🥈useEffect(处理副作用)🔋useCallback(记忆函数&#…...
Ubuntu20.04下noetic版本ros安装时rosdep update失败解决方法【一行命令】
一、问题: 安装完ros后,需要执行sudo rosdep init,但是在没有全局科学上网的前提下,执行sudo rosdep init势必会报错: ERROR: cannot download default sources list from: https://raw.githubusercontent.com/ros/r…...
Vue2.0开发之——购物车案例-Footer组件封装-计算商品的总价格(51)
一 概述 App.vue中计算勾选商品的总价格定义子组件Footer中的商品总价格将App.vue中商品的总价格传递给Footer显示 二 App.vue中计算勾选商品的总价格 2.1 商品总价格的计算逻辑 所有勾选商品的价格*数量 2.2 App.vue中通过计算属性计算总价格 通过计算属性计算总价格 co…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...



