【Linux】Linux项目自动化构建工具——make/Makefile

news2024/10/6 18:31:20

我举报,有人不学习!!!
在这里插入图片描述

文章目录

  • 一、makefile原理
  • 二、初步理解makefile的语法
    • 1.gcc如何得知,源文件不需要再编译了呢?
    • 2.为什么执行的指令是make和make clean呢?
  • 三、makefile的推导规则
  • 四、Linux小程序—进度条
    • 1.缓冲区概念
    • 2.回车换行
    • 3.倒计时小程序
    • 4.进度条



一、makefile原理

1.
makefile文件既可以写成makefile,也可以写成Makefile

2.
makefile文件中,要写的是依赖关系和依赖方法,例如生成的可执行程序mycode依赖的就是mycode.c源文件,没有这个源文件,就没有mycode这个可执行程序,生成可执行程序的过程中又依赖方法gcc mycode.c -o mycode也就是需要gcc来编译链接生成可执行程序。

vim makefile

// 下面是makefile文件的内容
mycode:mycode.c
       gcc mycode.c -o mycode  

二、初步理解makefile的语法

第一行是依赖关系,第二行必须以Tab键开头!!!,第二行写的是依赖方法
依赖关系可以为空

  1 mycode:mycode.c
  2     gcc mycode.c -o mycode
  3 
  4 .PHONY:clean
  5 clean:                                                                                                                                                                
  6      rm -f mycode

1.
被.PHONY:关键字修饰的对象是一个伪目标,该目标总是被执行的。
由于第一条依赖关系和依赖方法没有被.PHONY:修饰,所以如果命令执行过,且源文件没有被改动过的话,make是不允许连续多次执行的,但第二条依赖关系和依赖方法被.PHONY:修饰了,所以它是可以多次执行的

2.
换句话说,有了关键字.PHONY:修饰过后,就不要通过对比源文件和可执行程序Modify时间来判断是否能够执行指令了,不走这套规则,我让你执行,你就一直给我执行就OK了

在这里插入图片描述

1.gcc如何得知,源文件不需要再编译了呢?

Modify代表文件内容被修改的时间,Change代表文件属性被修改的时间,Access代表最后一次访问文件的时间,值得注意的是,文件大小也算文件的属性

1.
有时候访问文件的时间Access被更新的不是很灵敏,以前老的操作系统内核,对于这件事的原则就是,只要你访问了,就立马更新时间,但现在的操作系统内核,过一段时间之后才会更新我们的访问文件时间。
原因:文件操作的时候,改文件就一定会访问文件,但访问文件不一定该文件,所以访问文件的次数太多了,要进行更多次的IO,并且文件访问的时间基本没有人关心。

在这里插入图片描述
2.
一定先有源文件再有可执行程序,所以源文件的Modify时间一定要比可执行程序的Modify时间更早,所以gcc识别要不要重新编译,比较的就是源文件和可执行程序的文件内容修改时间。如果可执行程序更早,说明源文件被修改了,那就需要重新编译,如果源文件早,说明可执行程序被修改过,不需要重新编译。

当已经使用make指令过后,无法继续使用时,我们可以touch更新一下源文件的时间,这个时候就又可以用make指令了,这就证明了我们上面的结论。

touch mycode.c //touch后面跟上已存在的文件,可以更新此文件的三个时间。

2.为什么执行的指令是make和make clean呢?

make也可以跟上mycode使用,make默认从上到下扫描文本makefile的时候,第一个扫描到的目标文件可以省略名称使用,例如直接使用make,执行的就是makefile里面的第一个目标文件,并且默认情况下makefile只形成一个目标文件,也就是总目标文件只能有一个。

make mycode 
make
make clean

三、makefile的推导规则

在这里插入图片描述

  1 mycode:mycode.o
  2     gcc mycode.o -o mycode                                                                                                                                            
  3 mycode.o:mycode.s                  
  4     gcc -c mycode.s -o mycode.o       
  5 mycode.s:mycode.i                     
  6     gcc -S mycode.i -o mycode.s
  7 mycode.i:mycode.c              
  8     gcc -E mycode.c -o mycode.i
  9                  
 10 .PHONY:clean     
 11 clean:           
 12      rm -f mycode

1.
根据依赖关系列表,make先找mycode发现没有,那就去找mycode依赖的mycode.o,结果发现也没有,那就去找mycode.o依赖的mycode.s,结果发现还是没有,那就去找mycode.s依赖的mycode.i,结果没找到,那就去找mycode.i依赖的mycode.c结果找到了,那就执行他们之间的依赖方法,然后.i就有了,那就再一点一点向上执行每条依赖方法

2.
这就是整个make的依赖性,类似于堆栈结构,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。

四、Linux小程序—进度条

1.缓冲区概念

1.
如果加上\n那就会先显示you can see me然后停下来2秒钟,如果没有\n的话,那就会先停下来2秒,然后才显示出you can see me。

2.
第一种拥有\n可以立即输出的原因是因为,\n是行缓冲,只要遇到\n就会立马将这一行的内容输出到显示器上面

3.
针对第二种没有\n的情况,首先printf语句肯定是要先执行的,唯一的可能性就是,这个you can see me没有被立即显示出来,等到走完sleep语句,它才显示出来,在未显示的这段时间里面,you can see me一直被存储在行缓冲区里面

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 
  4 int main()
  5 {
  6     printf("you can see me ........\n");
  7     sleep(2);                                                                                                                                                         
  8     return 0;
  9 }
  
	// 可以利用fflush(stdout)语句来刷新缓冲区,这样数据就会立马显示出来
	

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 
  4 int main()
  5 {
  6     printf("you can see me ........");
  7     sleep(2);                                                                                                                                                         
  8     return 0;
  9 }

2.回车换行

理论上,回车和换行不是一个概念,换行是回到当前行的最开始,换行是将光标挪到下一行相同的光标位置,\r是回车\n是换行,\r\n合起来我们称之为回车换行。

语言层面上,\n就是回车换行,因为编译器在内部对于\n做了特殊处理,回车换行其实分成两步,先换行,再回车。

例如下面老式键盘的回车形状,是先向下再向左的。
在这里插入图片描述

3.倒计时小程序

1.
显示器能够显示各种符号,包括数字,汉字,字母等等,这些都被计算机看作符号,只不过人把它分为数字还是汉字,字母等,能够显示这么多符号是因为显示器面板上有各种像素点,点亮对应显示器上的像素点,就可以给人类显示出来各种各样的符号了,并且凡是能够显示到显示器上的,其实都是字符

在这里插入图片描述

2.
如果我们重新在第一个像素点输入8,那么这个像素点就会重新显示8,将9覆盖掉,基于这样的原理,我们就可以写一个倒计时小程序了。

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 int main()
  4 {
  5     int cnt=10;
  6     while(cnt)
  7     {
  8         printf("剩余时间:%2d\r",cnt);
 			// 利用\r回车来实现同一个像素点,显示多个数字,这样看起来就像倒计时                                                                                                                          
  9         fflush(stdout);
  			// 每次刷新一下缓冲区,立马显示数据
 10         cnt--;
 11         sleep(1);
 12     }
 13     return 0;
 14 }

4.进度条

gcc的-D选项可以帮助我们在命令行中完成某些变量的定义,例如下面定义了进度条的样式为N=1时的样式。

ProcessOn文件依赖main.c和process.c源文件,所以依赖关系和依赖方法如下:

Makefile文件内容

  1 ProcessOn:main.c process.c
  2     gcc main.c process.c -o ProcessOn -D N=1                                                                                                                          
  3 
  4 .PHONY:clean
  5 clean:
  6     rm -f ProcessOn

main.c文件内容

  1 #include "process.h"                                                                                                                                                  
  2 
  3 int main()
  4 {
  5     ProncessOn();
  6     return 0;
  7 }

process.h文件内容

  1 #pragma once 
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <unistd.h>
  5 
  6 #define NUM 101
  7 #define S_NUM 5                                                                                                                                                       
  8 
  9 extern void ProncessOn();

\033[42;34m 输出的内容 \033[0m这是内容的颜色控制
usleep代表的是微秒
%%在printf中可以输出显示为一个%号
-100可以控制进度条宽度为100位宽并且每次左对齐输出字符数组bar

C语言printf输出颜色控制

process.c文件内容

    2 #include "process.h"
    3 
    4 char style[S_NUM]={'*','#','-','.','+'};
    5 五种风格,可以在makefile文件中修改N,以控制风格样式
    
    6 void ProncessOn()
    7 {
    8     int cnt=0;
    9     //循环101次
   10     char bar[NUM];
   11     memset(bar,'\0',sizeof(bar));
   12 
   13     const char*lable="|\\-/";
   14 
   15     while(cnt<=100)
   16     {
   17         //printf("[%-100s][%-3d%%][%c]\r",bar,cnt,lable[cnt%4]);
   18         printf("\033[42;34m[%-100s][%-3d%%][%c]\033[0m\r",bar,cnt,lable[cnt%4]);                                                                                    
   19         fflush(stdout);
E> 20         bar[cnt++]=style[N];
   21         usleep(60000);
   22     }
   23 
   24     printf("\n");
   25 }

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

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

相关文章

2023年1月数据治理认证DAMA-CDGA/CDGP(线上)招生简章

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

C语言刷题系列——17.计算平均成绩 18.找出总分最高的学生19.通讯录排序

结构 - PTA练习题&#x1f424;计算平均成绩&#x1f3c0; 题目要求&#x1f3c0; 题解&#x1f4bb;step1.定义结构体&#x1f4bb;step2.输入N&#xff1b;随后N行 每行给出一位学生的信息&#x1f4bb;step3.求平均值&#x1f4bb;step4.输出平均线以下的学生的信息&#x1…

数据可视化最简单的方式-饼状图,折线图,条形图

一个软件或者网站分为前端&#xff0c;后端。 后端传统意义就是处理后端的数据。 后端又分为数据库编程人员和后端业务逻辑人员。 前端顾名思义解决后端传递的数据。传递的数据如何显示是前端人员考虑的问题。 前端人员不光要设计好网页界面&#xff0c;而且要将数据的可视…

嵌入式:ARM协处理器指令总结

文章目录&#xff08;一&#xff09;协处理器的数据操作二进制编码汇编格式&#xff08;二&#xff09;协处理器的数据存取二进制编码汇编格式&#xff08;三&#xff09;协处理器的寄存器传送二进制编码汇编格式未使用的指令空间ARM支持16个协处理器&#xff0c;用于各种协处理…

java Redis基础 数据类型 常用命令 java中使用Redis

Redis是一个基于内存的key-value结构数据库。 Redis入门 Redis简介 Redis应用场景&#xff1a; Redis 下载与安装 Windows版下载地址&#xff1a;https://github.com/microsoftarchive/redis/releases Linux版下载地址&#xff1a; https://download.redis.io/releases/ Red…

Java 中的main方法原理介绍。

//深入了解main方法 // 解释main方法的形式为什么是这样写的&#xff1f; // public static void main(String[] args) // 问题1&#xff1a;是谁调用main方法&#xff1f; // java虚拟机调用main方法&#xff0c;所以main的访问权限是public // 问题2&#xff1a;为什么是st…

电竞游戏蓝牙耳机哪个牌子好?电竞游戏蓝牙耳机排行榜

喜欢玩游戏或是追剧的话&#xff0c;佩戴蓝牙耳机更加不易受到外界的干扰&#xff0c;传输效果好的蓝牙耳机能够带来更好的画面感和立体感&#xff0c;那么电竞游戏蓝牙耳机哪个牌子好呢&#xff1f;以下是小编整理的几款当前值得入手的游戏蓝牙耳机。 第一款&#xff1a;南卡…

Java多线程之线程安全问题

文章目录一. 线程安全概述1. 什么是线程安全问题2. 一个存在线程安全问题的程序二. 线程不安全的原因和线程加锁1. 案例分析2. 线程加锁2.1 理解加锁2.2 synchronized的使用2.3 再次分析案例3. 线程不安全的原因三. 线程安全的标准类一. 线程安全概述 1. 什么是线程安全问题 …

【QGIS入门实战精品教程】7.1:QGIS面状数据符号化设置案例教程

本文讲解QGIS空间数据符号化设置。 文章目录 一、符号化模式详解1. 单一色彩2. 字段分类3. 渐进4. 基于规则5. 翻转多边形6. 2.5维二、样式文件的保存与使用1. 保存样式文件2. 载入样式文件一、符号化模式详解 1. 单一色彩 数据加载后,默认显示单一色彩符号化模式,可以进行…

采购管理系统能为企业带来哪些好处?

随着信息化技术的不断发展&#xff0c;很多企业采购组织利用信息化手段来进行采购管理已然成为了一种趋势。 而且在日趋激烈的市场竞争与疫情影响下&#xff0c;企业的成本竞争优势显得尤为重要&#xff0c;据有关调查数据显示&#xff0c;许多企业成本中的70%是采购成本&…

[Flask]数据库的连接和操作

一、安装连接程序 在控制台中使用语句 pip install pymysql 即可安装 同时为了使用ORM对数据库进行操作&#xff08;而非sql语句&#xff09;&#xff0c;还需要安装SQLAlchemy pip install flask-sqlalchemy 二、使用Navicat管理数据库 安装Navicat软件&#xff0c;本体需要…

软件企业认证的条件是什么?

一、双软认证企业的认证标准&#xff1a; 1.企业法人是在我国的境内设立的企业法人; 2.企业计算机的软件开发和生产制造、系统集成、应用服务和其他有关技术服务为其经营业务及主要营业收入; 3.有一种以上由本企业开发或是由本企业具备知识产权的软件产品&#xff0c;或给…

绪论

&#x1f64c;作者简介&#xff1a;数学与计算机科学学院出身、在职高校高等数学专任教师&#xff0c;分享学习经验、生活、 努力成为像代码一样有逻辑的人&#xff01; &#x1f319;个人主页&#xff1a;阿芒的主页 ⭐ 高等数学专栏介绍&#xff1a;本专栏系统地梳理高等数学…

网络交换的技术

文章目录1、背景2、电路交换2.1、电路交换的特点2.2、电路交换的缺点3、分组交换3.1、分组交换的主要特点3.2、分组交换的传输单元3.3、分组交换的优点3.4、分组交换的缺点4、报文交换5、三种报文的区别1、背景 网络交换技术共经历了四个发展阶段: 电路交换技术(19世纪末)报文…

带你学懂数据结构中的八大排序(上)

✨个人主页&#xff1a; Yohifo &#x1f389;所属专栏&#xff1a; 数据结构 | C语言 &#x1f38a;每篇一句&#xff1a; 图片来源 Every challenge, every adversity, contains within it the seeds of opportunity and growth. 每个挑战&#xff0c;每次逆境&#xff0c;里…

山外山在科创板上市:市值约47亿元,高光勇为实际控制人

12月26日&#xff0c;重庆山外山血液净化技术股份有限公司&#xff08;下称“山外山”&#xff0c;SH:688410&#xff09;在上海证券交易所科创板上市。本次上市&#xff0c;山外山的发行价格为32.30元/股&#xff0c;发行市盈率为297.74倍。 据贝多财经了解&#xff0c;山外山…

vivo 低代码平台【后羿】的探索与实践

作者&#xff1a;vivo 互联网前端团队- Wang Ning 本文根据王宁老师在“2022 vivo开发者大会"现场演讲内容整理而成。公众号回复【2022 VDC】获取互联网技术分会场议题相关资料。 本文主要从前后端分离的低代码方案、自研高性能渲染引擎、高效的可视化配置方案、千亿级内容…

基于yolov5s实践国际象棋目标检测模型开发

在我前面的一篇文章中讲解实现了基于改进的yolov5s-spd模型实现了五子棋目标对象检测模型系统的设计开发&#xff0c;这里紧接前文&#xff0c;突发奇想&#xff0c;是否可以借鉴同样的思路实现象棋的检测模型开发呢&#xff1f;理论上面肯定是可以的&#xff0c;但是实际效果如…

FineReport企业报表-配置MySQL8外接数据库(2)

1. 配置外接数据库 1.1 外接数据库配置入口 外接数据库的配置入口&#xff0c;有三种形式&#xff1a; 1&#xff09;超级管理员第一次登录数据决策系统时&#xff0c;即可为系统配置外接数据库。如下图所示&#xff1a; 2&#xff09;对于使用内置数据库的系统&#xff0c;管…

burpsuite——身份验证

文章目录通过不同响应枚举用户名2FA 简单旁路密码重置破坏逻辑通过细微不同的响应枚举用户名通过响应计时的用户名枚举破解暴力保护&#xff0c;IP 封锁通过帐户锁定的用户名枚举2FA 破坏逻辑暴力破解保持登录状态的 cookie通过不同响应枚举用户名 就是所谓的暴力破解&#xff…