【Linux】Linux项目自动化构建工具make makefile

news2024/10/7 2:22:30

文章目录

  • 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

image-20230301182531751

这里分别是我们的C语言源文件和makefile的内容,然后我们使用make指令

image-20230301182820292

可以看到,使用make指令之后,就执行了makefile的第一行,也就第一个依赖方法。当执行make clean时,执行了clean的内容。这样就完成了我们所需要的功能

下面,我们来详细分析一下上面范例中的各个代码的作用

3.原理

首先明确一点,make/makefile的存在是为了构建项目,构建项目需要依赖关系和依赖方法。举个例子,学生时代的我们都会问父母要钱,要钱的时候,我们会说“老爸,我没钱了,给我打钱”,这里前面半句话就是表明了依赖关系:我是你儿子,你是我爸爸,后面半句话就是表明了依赖方法:给我打钱

所以,在makefile中需要写的就是依赖关系和依赖方法,然后使用make去通过依赖关系执行依赖方法,从而产生我们需要的文件或者指令。

make是如何工作的?

  1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“test_make”这个文件,并把这个文件作为最终的目标文件。
  3. 如果test_make文件不存在,或是test_make所依赖的后面的test_make.c文件的文件修改时间要比hello这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成hello这个文件。
  4. 如果test_make所依赖的test_make.c文件不存在,那么make会在当前文件中找目标为test_make.c文件的依赖性,如果找到则再根据那一个规则生成test_make.c文件。(这有点像一个堆栈的过程)
  5. 当然,你的.c文件和.h文件是存在的啦,于是make会生成 test_make.c 文件,然后再用 test_make.c 文件声明make的终极任务,也就是执行文件test_make了。
  6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
  7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
  8. 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这个目标指令的,他的目的就是为了清除我们编译好的工程文件。

image-20230302194316562

但是我们回到上述实例中,可以发现,多了一行内容,是我们不理解的东西,那么它是什么呢?

.PHONY:表示被该关键字修饰的对象是一个伪目标,这里我们引入了一个新的概念,叫做伪目标

什么是伪目标?

image-20230302194910342

还是使用之前的那个test_make,我们发现,当该路径下没有目标文件的时候,我们能够正常的执行make指令,但是当我们想再次执行make指令的时候,发现出现了提示,没有办法正常执行make指令。反而,我们在执行make clean的时候,没有这种情况,能够连续执行任意次的make clean。这就是伪目标的作用伪目标表示该目标是永远被执行的!!!

对于上述的情况,我们只需要再修改一下源文件test_make.c,就会发现make又可以正常执行一次了。这是因为,make会识别我们上一次编译之后,源文件是否已经被修改,如果没有被修改,就不需要再次执行编译操作,(这一点是很重要的,一个中大型的项目,编译所花的时间短则几十分钟,长则几个小时甚至十几个小时)。

那么make是怎么知道源文件有没有被修改的呢?

答案是比较时间,比较源文件和目标文件的内容修改时间

我们知道,是先有源文件,在有目标文件的,所以,我们只需要比较源文件和目标文件的内容修改时间,如果源文件的内容修改时间早于目标文件的修改时间,那就说明源文件在生成目标文件之后,没有被更改,所以就没有再次编译的必要,否则就需要再次编译。

5. 文件属性中的三个时间

上面我们讲到了文件的修改时间,在这里我们详细介绍一下文件的“三个时间”。

使用stat指令,我们可以看到文件的详细信息,其中就包括了文件的创建时间,修改时间与最后一次访问时间

image-20230302202319634

对于modify和change的时间是容易理解的,但是access的时间改变规则有些不一样

因为对一个文件的访问,是很频繁的,如果每一次的访问,都要修改access时间的话,会导致系统的负荷太大,所以新的Linux内核就对access时间的修改规则做了修正,变成了根据一段时间内访问频率再去更新。

6. Linux下第一个小程序——进度条

6.1 前置知识1:缓冲区

image-20230305232419504

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

image-20230305233129951

然后我们发现该程序可以正常执行输出然后再停顿了。

6.2前置知识2:回车换行

在刚刚,我们提到了回车换行的概念,但是,回车和换行是两个概念,回车表示的是回到当前行的开头位置,用\r表示,换行表示光标换到下一行的同一位置,但是到这里就会有疑问,我们键盘上的enter键,一般不就是叫做回车键嘛?我们注意一下早期的键盘上,回车键是什么样子的

image-20230305234851852

用了一个向下和向左的箭头表示着这个键的作用是让光标去到下一行的开头。

那么如果不换行,只回车的话,会出现什么情况呢?

答案是会将屏幕上当前行的内容覆盖掉

那么,利用这种特性,我们能够写出一个简易的倒计时程序

image-20230306000437668

运行的结果是这样的:

请添加图片描述

这就是我们利用缓冲区和回车换行的特性写出来的简易倒计时。

6.3进度条的实现

有了上述的两个前置知识,我们就可以利用已知的知识写出进度条啦

接下来我们尝试一下多文件编程,首先定义一下头文件和主要的实现源文件,还有主函数文件,分别命名为process.h,process.c,main.c,然后对于一整个项目,我们要写一下makefile文件所以一共要创建四个文件

$ touch makefile process.c process.h main.c

image-20230306003526561

image-20230306003648411

各个部分代码如上,然后使用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就可以查看提交日志

image-20230306005535118

本节完。。。

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

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

相关文章

【C++】位图+哈希切割+布隆过滤器

文章目录一、位图1.1 位图概念1.2 位图实现1.2.1 把x对应比特位0置11.2.2 把x对应比特位1置01.2.1 查看x对应比特位1.3 位图源码1.4 位图的应用二、哈希切割(处理海量数据)三、布隆过滤器3.1 布隆过滤器的概念3.2 布隆过滤器的应用场景3.3 布隆过滤器的实…

zookeeper安装使用

一、因使用kafka 需使用zookeeper,此处使用单节点 ZooKeeper有两种安装模式,最简单的方式是单机模式(standalone mode),它只需要在一台机器上面运行,另一种方式是集群模式,集群模式需要多台服务器部署。 Z…

Java中垃圾回收(GC)基本概念

如果想真正理解GC,则需要循序渐进,由浅入深的了解GC,从本篇文章开始我们详细介绍Java中的GC,本篇文章我们通过4个主题先介绍垃圾回收的基本概念一、Java中什么是GC,为什么需要GC二、早期垃圾回收三、Java垃圾回收机制四…

DockQuery x 达梦 国产数据库生态“加速跑”

「数字化」是当今社会最先进和最具穿透力的生产力,近十年里开展着气势磅礴的发展。而信创产业则是保障中国经济数字化转型平稳健康发展的基础。 随着信创产业规模不断扩大,国产数据库市场释放出前所未有的活力。达梦作为国产数据库领头羊,坚…

Redis进阶之事物持久化

Reis进阶Redis事物Redis管道Redis持久化RDB持久化RDB持久化优缺点分析RBD文件修复&禁用RDB快照AOF持久化AOF优缺点&AOF重写机制AOF&RDB混合写机制Redis事物 什么是事物?相信学过数据库的铁子们都知道事物是什么。在MySQL当中事物是指和数据库连接的一次…

在面试时候,如何简明扼要简述产品流程

下面这个图是我今天总结的,我把它上传到这里来,然后逐一按点来解释,为了迎合面试,所以每个点尽量不超过140字。(觉得OK的,请点赞哦!)图片过大,请点击放大后按“F”键查看原图。或下载后查看&…

IT项目经理的自我修养手册

在不断进步的时代,任何岗位职责都是一个责任、权力与义务的综合体,有多大的权力就应该承担多大的责任,有多大的权力和责任应该尽多大的义务,任何割裂开来的做法都会发生问题。那么作为IT项目经理的岗位职责,我大概列举…

vue实现输入框中输完后光标自动跳到下一个输入框中

前言 最近接到这么一个需求,做一个安全码的输入框,限制为6位数,但是每一个写入的值都是一个输入框,共计6个输入框,当前输入框写入值后,光标自动跳到下一个输入框中,删除当前输入框写入的值后再自…

秒懂算法 | 基于主成分分析法、随机森林算法和SVM算法的人脸识别问题

本文的任务与手写数字识别非常相似,都是基于图片的多分类任务,也都是有监督的。 01、数据集介绍与分析 ORL人脸数据集共包含40个不同人的400张图像,是在1992年4月至1994年4月期间由英国剑桥的Olivetti研究实验室创建。 此数据集下包含40个目录,每个目录下有10张图像,每个…

Mysql下载安装详细笔记

MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。 一、下载mysql安装包 1. 登录官方网站https://www.mysql.com/ 2. 进入Down…

[Latex]参考文献的格式:数字,作者+年份

参考资料: 《使用 natbib 进行参考文献管理》 《bibliographystyle类型》 《\usepackage{natbib}在latex模板写作》 《LaTeX中的参考文献——作者年代引用》 文章目录[TOC]一、共同的参考文献和正文二、参考文献的引入方法2.1 声明引入的使用包(usepackage)2.2 正文的引用\…

C语言-基础了解-09-C循环

C循环 一、C循环 循环语句允许我们多次执行一个语句或语句组,下面是大多数编程语言中循环语句的流程图: 二、循环类型 2.1 while 循环 当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。 语法 while(condition) { …

【虹科案例】虹科任意波形发生器在量子计算中的应用

虹科AWG在量子计算中的应用精度在研究中始终很重要,很少有研究领域需要比量子研究更高的精度。奥地利因斯布鲁克大学的量子光学和量子信息研究所需要一个任意波形发生器(AWG)来为他们的研究生成各种各样的信号。01无线电频率第一个应用是在射…

C++——类型转换

目录 C语言中的类型转换 C强制类型转换 static_cast reinterpret_cast const_cast dynamic_cast 延伸问题 RTTI(了解) C语言中的类型转换 在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或…

JAVA开发(Spring Gateway 的原理和使用)

在springCloud的架构中,业务服务都是以微服务来划分的,每个服务可能都有自己的地址和端口。如果前端或者说是客户端直接去调用不同的微服务的话,就要配置不同的地址。其实这是一个解耦和去中心化出现的弊端。所以springCloud体系中&#xff0…

aws apigateway 使用restapi集成http

参考资料 https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/services-apigateway-tutorial.html restapi代理集成http 在 HTTP 代理集成中,apigateway会将客户端提交的方法请求传递至后端。传递的请求数据包括请求标头、查询字符串参数、URL 路径变量和paylo…

SVN项目迁移到Git方法

本文记录如何将SVN项目迁移到Git,并保留提交日志信息。 目录Git和SVN差异环境准备Git安装、配置项目迁移1. 将源SVN库转换到Git本地仓库2. 添加Git远程库地址3. 推送代码到Git常见错误参考文档Git和SVN差异 Git是一个开源的分布式版本控制系统,由Linux之…

一、策略模式的使用

1、策略模式定义: 策略模式(Strategy Pattern)定义了一组策略,分别在不同类中封装起来,每种策略都可以根据当前场景相互替换,从而使策略的变化可以独立于操作者。比如我们要去某个地方,会根据距…

云原生应用配置管理的5个最佳实践

引言 在复杂的云原生应用程序中管理配置信息是非常困难的,似乎到处都有配置。在使用基于微服务架构的云原生应用程序中,配置问题成倍增加。 配置无处不在。有针对网络的配置,比如路由规则、端口控制、负载均衡,有针对数据库的配置…

JavaScript Boolean 布尔对象

文章目录JavaScript Boolean 布尔对象Boolean 对象Boolean 对象属性Boolean 对象方法检查布尔对象是 true 还是 false创建 Boolean 对象JavaScript Boolean 布尔对象 Boolean(布尔)对象用于将非布尔值转换为布尔值(true 或者 false&#xff0…