Linux开发工具Make/Makefile篇

news2024/10/7 10:20:36

在这里插入图片描述

文章目录

  • 🍈0. 前言
  • 🍉1. 见见猪跑
  • 🍊2. 依赖关系和依赖方法
  • 🍋3. 清理
  • 🍌4. 不可多次编译的原理
    • 🍍4.1 原因
    • 🍍4.2 stat命令
    • 🍍4.3 验证
  • 🥭5. 伪目标
  • 🍎6. 取消回显

🍈0. 前言

我们使用gcc/g++编译代码时,每次都要输入一长串的指令,对于单个文件或者文件较少的时候,我们还能接受,可是当文件较多的时候,我们再一个一个编译,就会比较麻烦。Linux中make命令加上Makefile文件搭配使用,就可以完成项目的自动化构建。

🍉1. 见见猪跑

C代码

#include<stdio.h>
int main()
{
	printf("hello linux\n");
	printf("hello linux\n");
	printf("hello linux\n");
	return 0;
}

创建makefile文件

mkdir makefile

写入依赖关系、依赖方法

code:code.c
	gcc -o code code.c
clean
	rm -f code

执行make命令

image-20230706141348815

这一套流程下来,就是简单的自动化编译与清理,这里要清楚的是make是一个命令,而makefile是一个文件。下面我们来讲解一下这其中原理。

🍊2. 依赖关系和依赖方法

打个比方:

期末考试考完了,在路上碰见了老师,你想求老师捞一捞。上前打招呼,“老师,我是你学生xxx”,这句话就是说明你和这个老师的关系,这个就是依赖关系

答完招呼,你就说出了你的想法,“老师,捞一把,卷子我全部都写满了”,老师说“好的好的,我尽量,我尽量”。而这个向老师提出的需求就是依赖方法

image-20230706144218282

知道了这个概念,再来看一下其中的流程,将makefile文件写的复杂一点

code:code.o
	gcc -o code code.o
code.o : code.s
	gcc -c code.s -o  code.o
code.s : code.i
	gcc -S code.i -o code.s
code.i : code.c
	gcc -E code.c -o code.i

然后我们再执行make指令:

image-20230706151232954

我们发现,如果按顺序来执行的话,应该是先执行gcc -o code code.c,但是这个输出的顺序并不是这样,而是反正输出的。

这里其实是因为code依赖的是code.o文件,而当前目录并没有这个文件,于是需要生成一个code.o的文件,发现依赖文件中有生成code.o的依赖关系和依赖方法,依次类推。这就很像递归的过程

所以我们可以知道make会自动的推导makefile中的依赖关系,而这种过程是一种栈式的结构

Tips:

即使我们调换了其中的顺序,也可以生成,就类似调用函数,不管这个函数在哪,只要能调到就行;

但是如果这其中缺少了环节,那么就不会生成了。

image-20230706153940612

当然了,这只是演示,在实际操作的时候,就不要写这么复杂,能一步到位就一步到位。

🍋3. 清理

当项目不要的时候,需要进行清理。我们就可以到makefile文件中写入清理的依赖关系和依赖方法:

clean:
	rm -f code code.i code.o code.s

clean不需要依赖其他的文件,依赖关系为空

执行make clean指令,就删除了我们不需要的项目文件。

image-20230706155318132

那为啥清理的时候需要make clean呢?能不能也像创建可执行文件时,直接使用make呢?

我们将makefile文件稍微下一下,将clean移到最前面来,然后再执行make指令:

image-20230706155921450

这样我们使用make的时候,就默认变成了清理操作。

这是因为make会自顶向下去扫描,将第一个依赖充当为默认操作

🍌4. 不可多次编译的原理

🍍4.1 原因

image-20230706161016574

当我们多次make时,系统会提示我们code是最新的,就不让我们继续make了。

如果将code.c文件修改一下,会发现又能重新make了,但也是只能make一次。

image-20230706161403362

出现这种情况是因为编译器认为没有必要,既然文件没有发生改变,那就没有必要再编译一次,就算编译了,也是一样的,所以为了节省资源,编译器就会选择不编译,出发这个文件内容发生改变。

VS2022为例:

1

那这是如何做到的呢?

对于源文件生成可执行程序,那么肯定是先有源文件,再有可执行程序,在这种情况下,源文件的修改时间肯定是在可执行程序之前

如果修改了源文件,那么源文件的修改时间肯定会比可执行程序要新

所以,这需要比较源文件和可执行程序的最近修改时间就行。

🍍4.2 stat命令

stat命令可以查看文件的详细信息,这里面就包含了文件的时间信息。

image-20230706191448757

  • Access:最近访问时间(打开、查看、修改),只要我们访问了该文件,就会被记录。

只要访问文件,Access就会改变,当多人协同操作的时候,有些文件可能会被频繁的访问,如果每次访问就修改时间,那么就每次都要去磁盘修改文件的属性,这就会十分影响效率。

在较新的版本中,Access的更新策略发生了改变,会根据ModifyChange的改变或者采用计数器等方式改变。

image-20230706202021463

  • Modify:对文件内容继续修改的时间

  • Change:文件属性改变的时间

image-20230706200108067

文件内容改变的时候,文件属性肯定会改变;文件属性改变,不一定会改变文件内容

image-20230706202655221

touch 文件名如果没有该文件,则创建该文件;

如果有了这个文件,则更新所以最新时间。

image-20230706202945963

🍍4.3 验证

了解了文件的时间关系,就能够解释前面的原因了,我们来验证一下

image-20230706204104579

🥭5. 伪目标

如果我们不想受这个的约束,想执行就执行,可采用.PHONY来修饰这个目标文件,让其是一个伪目标。

image-20230706204539503

当然,这里不建议将我们的可执行操作设为伪目标,一般采用将清理操作设为伪目标。

image-20230706205935176

🍎6. 取消回显

我们使用make时,每次都会将对应的方法回显出来,如果不想要回显,我们可以将依赖方法前面加上@

另外,使用$@(:$^自动化变量,引用目标和依赖项。

image-20230706211001200




以上就是make的基本操作了,大伙可以根据项目的实际需求和复杂性来扩展和定制Makefile。

那本次的分享就到这里啦,如果要帮助的话希望点赞支持一下,我们下期再见,如果还有下期的话。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/725014.html

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

相关文章

【如何用大语言模型快速深度学习系列】从word2vec、SVD到GloVe

三天热度果然名不虚传&#xff0c;写作的效率有所下降&#xff0c;但是只要坚持二十一天就能养成习惯啦&#xff01;冲冲冲&#xff01; 上一节回顾 文章链接 在上一章我们将词的概念&#xff0c;通过n-gram组合成了n个词的切片&#xff0c;终于将前后词之间建立了一个联系&a…

MySQL授权操作

目录 授权和撤销授权 创建用户 授权 撤销授权 授权其他用户与撤销权限 授权和撤销授权 创建用户 create user 用户名% identified by 密码; 示例&#xff1a;create user tom% identified by 123456; 授权 GRANT ALL ON 库名.表名 TO 用户名’客户端主机 ; 示例&a…

【动手学习深度学习--逐行代码解析合集】08模型选择、欠拟合和过拟合

【动手学习深度学习】逐行代码解析合集 08模型选择、欠拟合和过拟合 视频链接&#xff1a;动手学习深度学习–模型选择、欠拟合和过拟合 课程主页&#xff1a;https://courses.d2l.ai/zh-v2/ 教材&#xff1a;https://zh-v2.d2l.ai/ 1、生成数据集 import math import numpy a…

ROS:参数名称设置

目录 一、前言二、rosrun设置参数三、launch文件设置参数四、编码设置参数4.1C实现4.1.1ros::param设置参数4.1.2ros::NodeHandle设置参数 4.2python实现 一、前言 在ROS中节点名称话题名称可能出现重名的情况&#xff0c;参数名称也可能重名。 关于参数重名的处理&#xff0c…

Css:浮动相关

1.为什么需要浮动&#xff1f; 多个块级元素纵向排列找 标准流&#xff0c;多个块级元素横线排列找 浮动 2.浮动的特性 浮动会脱离标准流&#xff08;脱标&#xff09; 浮动的盒子不再保留原来的位置 3.清除浮动

BM68-矩阵的最小路径和

题目 给定一个 n * m 的矩阵 a&#xff0c;从左上角开始每次只能向右或者向下走&#xff0c;最后到达右下角的位置&#xff0c;路径上所有的数字累加起来就是路径和&#xff0c;输出所有的路径中最小的路径和。 数据范围: 1≤n,m≤500&#xff0c;矩阵中任意值都满足 0≤ai,j…

T100新程序的开发【完整步骤】

简易程序的开发 记录T100中一个简易程序的开发完整步骤。 一、程序基本数据设置作业 打开作业 azzi900,弹出作业详情。 新增一个程序编号。 一些属性概念 程序编号:手动输入你建立的新程序。程序名称:手动输入你建立的名称。归属模块:取决于你程序编号的第一个字母。归属…

C语言判断当前目录下是否存在某一个文件

要判断当前目录下是否存在文件A&#xff0c;可以使用C语言中的标准库函数access来实现。access函数用于检查指定文件是否存在及是否具有指定的访问权限。 #include <stdio.h> #include <unistd.h>int main() {const char* filename "fileName";// 检查…

MongoDB【Springboot访问MongoDB、MongoDB安全认证、MongoDB内置角色 】(五)-全面详解(学习总结---从入门到深化)

目录 Springboot访问MongoDB MongoDB安全认证 MongoDB内置角色 Springboot访问MongoDB MongoTemplate方式 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>…

【裸机开发】SPI 通信接口(一)—— SPI 通信流程及四种工作模式

目录 一、SPI 简介 二、SPI 的基本通信流程 三、SPI 的四种工作模式 1、极性和相位 2、四种工作模式 一、SPI 简介 SPI 采用主从的方式工作&#xff0c;可以一个主设备对应一个从设备&#xff0c;也可以一个主设备对应多个从设备。虽然是一个主设备对多个从设备的关系&am…

如何建立一套完整的人事管理制度?

一、什么是人事管理制度 人事管理制度是企业为有效管理和运营人力资源而建立的一系列规章制度、流程和政策。它是人力资源管理的基础&#xff0c;旨在确保企业拥有合适的员工队伍&#xff0c;并通过有效的管理和激励机制&#xff0c;使员工能够充分发挥自己的潜力&#xff0c;…

计算机网络 day2 物理层-数据链路层-帧-MAC地址 交换机的工作原理

目录 物理层&#xff08;physical layer&#xff09; 数据链路层&#xff08;Data link layer&#xff09; MAC地址&#xff1a; 网络地址&#xff1a; 帧的格式&#xff1a; MTU&#xff1a;最大传输单元 max transfer unit 1500 &#xff08;ip add可以查看&#xf…

【动态规划算法练习】day16

文章目录 一、完全背包1.题目简介2.解题思路3.代码4.运行结果 二、322. 零钱兑换1.题目简介2.解题思路3.代码4.运行结果 三、518. 零钱兑换 II1.题目简介2.解题思路3.代码4.运行结果 四、279. 完全平方数1.题目简介2.解题思路3.代码4.运行结果 总结 一、完全背包 1.题目简介 …

【百日冲大厂】第二十篇,牛客网选择题+编程题 字符串反转+公共子串计算(dp问题)

前言&#xff1a; 大家好&#xff0c;我是良辰丫&#xff0c;第二十篇,牛客网选择题编程题 字符串反转公共子串计算(dp问题).&#x1f49e;&#x1f49e;&#x1f49e;生活就像一只盲盒&#xff0c;藏着意想不到的辛苦&#xff0c;当然也有万般惊喜的可能。不管是次次都如愿以偿…

初学者一步步学习python 学习提纲

当学习Python时&#xff0c;可以按照以下提纲逐步学习&#xff1a; 入门基础 了解Python的历史和应用领域安装Python解释器和开发环境&#xff08;如Anaconda、IDLE等&#xff09;学习使用Python的交互式解释器或集成开发环境&#xff08;IDE&#xff09;进行简单的代码编写和…

浅谈C++下观察者模式的实现

为什么要有观察者模式 想象一个场景&#xff0c;有一只猫和一群老鼠&#xff0c;当猫出现的时候&#xff0c;每一只老鼠都要逃跑 用最简单的方法实现一个去模拟这一个过程 #include<iostream>class Mouse_1 {public:void CatCome(){std::cout<<"Mouse_1 Ru…

【MyBatis-Plus】DQL编程控制

1&#xff0c;DQL编程控制 增删改查四个操作中&#xff0c;查询是非常重要的也是非常复杂的操作&#xff0c;这块需要我们重点学习下&#xff0c;这节我们主要学习的内容有: 条件查询方式查询投影查询条件设定字段映射与表名映射 1. 条件查询 1. 条件查询的类 MyBatisPlus…

PHP 训练成绩管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 训练成绩管理系统 是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为PHP APACHE&#xff0c;数据库 为mysql5.0&#xff0c;使用php语言开发。 …

css设计表格圆角最简单的方法

代码如下&#xff1a; table {width: 100%;/* border-collapse: collapse; */background-color: #FBFBFB; /* 背景颜色; */border-collapse: separate; /* 让border-radius有效 */border-spacing: 0; /*表格中每个格边距设为0*/border: 1px solid #DFDFDF;/*边框*/border-radi…

软件测试面试简历,三年测试项目经验怎么写?

作为三年左右的测试工程师&#xff0c;简历上有五六个项目经历很正常&#xff0c;那如何设计这几个项目&#xff0c;其实设计好三两个就行&#xff0c;面试官能关注到的也只有最新的三两个&#xff0c;两年前的项目也没有关注的必要啦&#xff0c;所以在这两三个项目中一定要体…