Linxu自动化构建工具make/Makefile究竟时什么?

Linxu自动化构建工具make/Makefile究竟时什么?

  • 一、简介
  • 二、makefile文件制作(简洁版)
    • 2.1 源文件
    • 2.2 makefile如何制作
      • 2.2.1 依赖关系、依赖方法
      • 2.2.3 伪目标(清理文件资源)
  • 三、make/Makefile自动化原理
    • 3.1 伪目标为什么可以重复执行?
    • 3.2 make如何工作?
  • 四、Makefile简介版本
    • 4.1 版本一
    • 4.2 版本二
    • 4,3 版本三

一、简介

 在一个大型工程中,源文件不计其数。按照文件类型、功能、模块不同,放在不同的目录下。但哪些文件先编译,哪些文件后编译,哪些文件需冲重新编译,甚至更为复杂的功能操作,如果依靠程序员自身来控制,不仅效率低下,而且极其容易出错!为此,自动化构建工具诞生 —— make/Makefile
Makefile(或makefile)是一个脚本文件;而make是一个命令工具,用于解释Makefile中的指令,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。当我们在Makefile中一旦写好了编译方式,只需要一个make命令就可完成整个工程的自动化编译。

二、makefile文件制作(简洁版)

2.1 源文件

这里我们给出一段各位都记忆深刻的代码:(存在于code.c源文件中)

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

2.2 makefile如何制作

在工程中,最重要的就是通过源文件通过某种方式来形成可执行文件,以及项目资源的清理。现在的问题是如何通过makefile来达到上述目的呢?
我们只需要在Makefile文件中输入以下程序即可:(后续还会在修改)

mybin:code.c  #如果有多个源文件,code.c后可继续田间源文件 gcc code.c -o mybin #前面的空格只能按Tab键,不能输入4个空格(语法)
.PHONY:clean #伪目标                                                                                                                                                                   
clean:                         rm -f mybin

接下来我们来一一分析每段代码是什么意思,以及如何编写!

2.2.1 依赖关系、依赖方法

 第一行mybin:code.c 称为依赖关系冒号左边为目标文件;冒号左边为源文件(可以是多个)。
 第二行gcc code.c -o mybin称为依赖关系,及源文件通过何种方式来形成目标文件。需要特别注意的是:依赖关系前的空格只能通过Tab键实现,不可以是4空格或其他!!!

 比如假设我们需要通过main.c、code.c、test.c三个源文件通过gcc来编译形成mybin目标文件,所以代码为:

mybin:main.c code.c test.c gcc main.c code.c test.c -o mybin

mybin:main.c code.c test.c gcc -o mybin main.c code.c test.c  //(只需保证-o后紧跟的是目标文件即可)

2.2.3 伪目标(清理文件资源)

在上述代码中.PHONY:xxx文件名表示该目标文件为伪目标,表示该文件不需要依赖关系,并且总是被执行
现在我们分别运行伪目标文件和普通文件看看会发生什么?

【普通目标文件】:

请添加图片描述

【伪目标文件】:
请添加图片描述

 我们发现对于普通目标文件,一旦我们编译后就不能重复编译,否则会报make: ‘mybin' is up to date.;但对于伪目标文件来说可以重复执行。
 为什么会这样呢?

三、make/Makefile自动化原理

3.1 伪目标为什么可以重复执行?

在解决这个问题之前,我们需要先了解为什么普通目标文件不可以重复执行!

 在实际工程中,一个大型项目存在众多的源文件,我们需要对这些源文件进行编译形成可执行文件。但一旦编译好后,在下一次执行该文件时,我们只需要重新编译某些内容被修改过的源文件即可。如果每次执行都需要重新编译所有的源文件,不仅意义不大,还会导致效率大大降低!

那程序如何发现代码别修改过,需要重新编译了?

在Linux中,每个文件有3种时间:Access、Modify、change三种时间,分别代表文件被打开的时间、文件内容内修改的时间、文件属性被修改的时间。我们可以通过stat 文件名来查看文件的3种时间。
 其中,Access时间比较特殊。一般而言,一个文件被访问是非常频繁的。由于文件存在磁盘中,如果每次进入文件都修改文件的Access时间,这也意味着存在大量的访问磁盘的IO操作,变形的降低了操作系统的效率。为此,当代计算机一般都对更改Access时间做了次数限制,不同机器平台存在差异。只有达到一定次数时,才会修改Access时间
 由于我们最终目的是得到相应的可执行程序,所以我们可以通过对比源文件和可执行文件的Modify来判断哪些文件被修改过,需要重新编译。即源文件第一次形成可执行文件时,可执行文件的Modify > 源文件的Modify。一旦源文件内容被修改后,此时源文件Modify被修改为最新时间,此时源文件Modify > 可执行文件的Modify。而make如果识别到源文件Modify > 可执行文件的Modify,便会对源文件进行重新编译。

伪目标为什么可以重复执行?
 前面博主替代过,一旦文件通过.PHONY:文件名成为伪目标,此时该文件不在需要依赖关系。这也意味这该文件不需要对比任何时间,直接执行。即可以重复执行。

3.2 make如何工作?

 在默认情况下,只要我们输入make命令,此时make会在当前目录下查找名为Makefile或makefile的文件。如果找到,则它会将第一个目标文件作为最终的目标文件。
 如果第一个目标文件文件不存在,或是第一个目标文件所依赖的后面的 .o 文件的文件修改时间要比第一个目标文件新,那么,他就会执行后面所定义的命令来生成这个文件。如果第一个目标文件所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。
 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。make只管文件的依赖性,即,如果在找了依赖关系之后,冒号后面的文件还是不在,那么就不工作了。

四、Makefile简介版本

比如假设我们需要通过main.c、code.c、test.c三个源文件通过gcc来编译形成mybin目标文件,这里有3个版本。各位自行选择。

4.1 版本一

这个就是最简单版本,就不多说了。

mybin:code.c  gcc main.c、code.c、test.c -o mybin #前面的空格只能按Tab键,不能输入4个空格(语法)
.PHONY:clean #伪目标                                                                                                                                                                   
clean:                         rm -f main.c、code.c、test.c

4.2 版本二

在Makefile中,我们可以在指令前加上@符号,可以不在显示屏上回显文件执行的指令。同时$@表示冒号左边的目标文件,$^来表示冒号右边的所有源文件。
所以上述代码可修改如下:

mybin:main.c、code.c、test.c gcc &^ -o $@ #前面的空格只能按Tab键,不能输入4个空格(语法)
.PHONY:clean #伪目标                                                                                                                                                                   
clean:                         rm -f target

4,3 版本三

在make/Makefile中,支持变量化处理。有点类似于宏替换,具体如下:

cc=gcc
target=mybin.exe
src=main.c code.c test.c
#使用上述变量时,我们仅需通过$(变量)即可使用$(target):$(src)  $(cc) &^ -o $@ #前面的空格只能按Tab键,不能输入4个空格(语法)
.PHONY:clean #伪目标                                                                                                                                                                   
clean:                         rm -f target

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

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

相关文章

SpringBoot+Vue实现el-table表头筛选排序(附源码)

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;在笑大学牲 &#x1f39f;️个人主页&#xff1a;无所谓^_^ ps&#xff1a;点赞是免费的&#xff0c;却可以让写博客的作者开心好几天&#x1f60e; 前言 后台系统对table组件的需求是最常见的&#xff0c;不过element-ui的el…

Grpc项目集成到java方式调用实践

背景&#xff1a;由于项目要对接到grcp 的框架&#xff0c;然后需要对接老外的东西&#xff0c;还有签名和证书刚开始没有接触其实有点懵逼。 gRPC 是由 Google 开发的高性能、开源的远程过程调用&#xff08;RPC&#xff09;框架。它建立在 HTTP/2 协议之上&#xff0c;使用 …

D7805 正电压稳压电路应用——体积小,成本低,性能好

D7805 构成的 5V 稳压电源为输出电压5V&#xff0c;输出电流 1000mA 的稳压电源它由滤波电容 C1,C3,防止自激电容 C2、C3 和一只固定三端稳压器&#xff08;7805&#xff09;后级加 LC 滤波极为简洁方便地搭成&#xff0c;输入直流电压范围为 7~35V&#xff0c;此直流电压经过D…

yolov8-更换卷积模块-ContextGuidedBlock_Down

源码解读 class ContextGuidedBlock_Down(nn.Module):"""the size of feature map divided 2, (H,W,C)---->(H/2, W/2, 2C)"""def __init__(self, nIn, dilation_rate2, reduction16):"""args:nIn: the channel of input fea…

Hack The Box-Bizness

目录 信息收集 nmap dirsearch WEB Get shell 提权 get user flag get root flag 信息收集 nmap 端口扫描┌──(root㉿ru)-[~/kali/hackthebox] └─# nmap -p- 10.10.11.252 --min-rate 10000 -oA port Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-03-04 1…

力扣 第 387 场周赛 解题报告 | 珂学家 | 离散化树状数组 + 模拟场

前言 整体评价 手速场模拟场&#xff0c;思路和解法都蛮直接的。 所以搞点活 如果T2&#xff0c;如果不固定左上角&#xff0c;批量查询某个点为左上角&#xff0c;求满足总和 ≤ k \le k ≤k的子矩阵个数 如果T2&#xff0c;如果不固定左上角&#xff0c;求总和 ≤ k \le k…

Spring的Bean的生命周期 | 有图有案例

Spring的Bean的生命周期 Spring的Bean的生命周期整体过程实例化初始化服务销毁循环依赖问题 完整生命周期演示 Spring的Bean的生命周期 Spring Bean的生命周期&#xff1a;从Bean的实例化之后&#xff0c;通过反射创建出对象之后&#xff0c;到Bean称为一个完整的对象&#xf…

快上车:什么是人工智能?人工智能和普通程序的区别

什么是人工智能&#xff1f; 虽然AI历史很悠久&#xff0c;上个世纪50年代就有各种概念&#xff0c;但是发展很慢。第一次对人类的冲击就是1997年IBM深蓝击败国际象棋世界冠军&#xff0c;引起了人们的广泛关注&#xff0c;之后又销声匿迹。突然间2016人工智能alphaGO战胜了围…

具身智能计算系统,机器人时代的 Android | 新程序员

【导读】具身智能作为一种新兴的研究视角和方法论&#xff0c;正在刷新我们对智能本质及其发展的理解&#xff1a;传统的 AI 模型往往将智能视为一种独立于实体存在的抽象能力&#xff0c;而具身智能则主张智能是实体与其环境持续互动的结果。 本文深度剖析了具身智能计算系统…

程序员如何选择职业赛道?

一、自我评估与兴趣探索 程序员选择职业赛道时&#xff0c;可以考虑以下几个关键因素&#xff1a; 1、兴趣与热情&#xff1a;首先要考虑自己的兴趣和热情&#xff0c;选择符合个人喜好和激情的领域&#xff0c;能够激励自己持续学习和进步。 2、技术能力&am…

mysql5.7配置主从

原理&#xff1a; MySQL主从复制的工作原理如下:1. 主服务器产生Binlog日志当主服务器的数据库发生数据修改操作时,如INSERT、UPDATE、DELETE语句执行,主服务器会记录这些操作的日志信息到二进制日志文件中。2. 从服务器读取Binlog日志 从服务器会向主服务器发送请求,主服务器把…

微信小程序开发学习笔记《18》uni-app框架-网络请求与轮播图

微信小程序开发学习笔记《18》uni-app框架-网络请求 博主正在学习微信小程序开发&#xff0c;希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读uni-app对应官方文档 一、下载网络请求包 这个包是以前黑马程序员老师写的一个包&#xff0c;跟着课程学习&#x…

Open3D(C++) 指定点数的体素滤波

目录 一、算法原理1、算法过程2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、算法过程 对于数据量较大的点云,在后期进行配准时会影响计算效率。而体素格网…

LCR 170. 交易逆序对的总数

解题思路&#xff1a; 归并排序&#xff0c;在归并的过程中不断计算逆序对的个数 count mid -i 1&#xff1b;的来源见下图&#xff0c;因为两个数组都是单调递增的&#xff0c;所以如果第一个数组的前一个元素大于第二个数组的对应元素&#xff0c;那么第一个数组的这一元素…

借助Aspose.SVG图像控件,在 C# 中将图像转换为 Base64

Base64 编码是一种二进制到文本的编码方案&#xff0c;可有效地将二进制数据转换为 ASCII 字符&#xff0c;为数据交换提供通用格式。在某些情况下&#xff0c;我们可能需要将JPG或PNG图像转换为 Base64 字符串数据。在这篇博文中&#xff0c;我们将学习如何在 C# 中将图像转换…

分享经典、现代和前沿软件工程课程

随着信息技术的发展&#xff0c;软件已经深入到人类社会生产和生活的各个方面。软件工程是将工程化的方法运用到软件的开发、运行和维护之中&#xff0c;以达到提高软件质量&#xff0c;降低开发成本的目的。软件工程已经成为当今最活跃、最热门的学科之一。 本次软件工程MOOC课…

现在如何才能开通微信公众号留言功能?

为什么公众号没有留言功能&#xff1f;2018年2月12日之后直到现在&#xff0c;新注册公众号的运营者会发现一个问题&#xff1a;无论是个人还是企业的公众号&#xff0c;在后台都找不到留言功能了。这对公众号来说绝对是一个极差的体验&#xff0c;少了一个这么重要的功能&…

万村乐数字乡村系统开源代码:革命性引领,助推乡村振兴新篇章

如今&#xff0c;国际社会普遍认为信息化、数字化已是重大且不可逆转的发展趋势&#xff0c;如何让广大农村地区充分分享到这个发展带来的红利&#xff0c;从而提升农村的经济活力&#xff0c;确保村民生活质量不断优化&#xff0c;已然成为我们需要认真研究并积极解决的重大议…

Window下编写的sh文件在Linux/Docker中无法使用

Window下编写的sh文件在Linux/Docker中无法使用 一、sh文件目的1.1 初始状态1.2 目的 二、过程与异常2.1 首先获取标准ubuntu20.04 - 正常2.2 启动ubuntu20.04容器 - 正常2.3 执行windows下写的preInstall文件 - 报错 三、检查和处理3.1 评估异常3.2 处理异常3.3 调整后运行测试…

uniapp+vue基于Android的图书馆借阅系统qb4y3-nodejs-php-pyton

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 框架支持:springboot/django/php/Ssm/flask/express均支持 前端开发:vue 语言&#xff1a;pythonjavanode.jsphp均支持 运行软件:idea/eclip…