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

目录

一、make/Makefile的简单使用

二、Makefile 的语法规则

三、实现的原理

3.1 make/Makefile识别文件新旧

3.2 .PHONY修饰的伪目标总是被执行

3.3 make/Makefile是具有依赖性的推导能力的

四、语法技巧

五、注意事项


Linux中自动化构建项目最简单的方式:make/Makefile
make:是一个命令
Makefile:是一个在当前目录下存在的一个具有特定格式的文本文件。
(Makefile首字母可以小写,但建议使用大写)

makefile文件中,保存了编译器和链接器的参数选项,并且描述了所有源文件之间的关系。make程序会读取makefile文件中的数据,然后根据规则调用编译器,汇编器,链接器产生最后的输出。

一、make/Makefile的简单使用

  • 创建Makefile
    touch Makefile
  •  编写Makefile:
    vim Makefile
  • 编写要生成的可执行程序mybin和项目清理clean:
  • 使用make命令生成可执行程序
    make
  • 使用make命令进行项目清理
    make clean

二、Makefile 的语法规则

Makefile 中包括依赖关系(目标依赖)依赖方法(命令)
下面是 Makefile 中一些要素的基本语法规则:

目标:指定了要生成的文件或要执行的操作名。

例如:上面的mybin就是要生成的目标文件名

依赖:指定了目标所依赖的文件或其他目标。

例如:上面的test.c 是目标文件依赖的文件。一个目标文件可以有多个依赖文件,用空格分开。
目标和依赖构成了依赖关系

命令(依赖方法):包含了生成目标所需的具体操作步骤,通常是一条或多条 Shell 命令。

第二行必须以Tab开头,不能是空格,紧接着是生成目标文件的命令。

例如:上面的gcc test.c -o mybin -std=c99
(gcc test.c -o mybin 与gcc -o mybin test.c 相同,-o后面跟目标文件名即可)

伪目标:伪目标是指在 Makefile 中.PHONY定义的不对应实际文件的目标,通常用于执行一些特定的操作,比如清理临时文件。 
例如:上面的clean目标用于执行清理操作,删除mybin文件。
注:make默认执行的是第一行的命令,一般把清理工作放在最后面。

注释:使用 # 符号来添加注释,注释从 # 开始一直到该行的末尾。

变量:可以使用变量来存储命令选项、编译器名称等信息,然后在规则中引用这些变量。
语法格式:VAR_NAME = value

条件判断:可以使用条件判断(ifeq、ifdef 等)来根据不同的条件执行不同的命令。

函数:Makefile 支持一些内置函数,可以用于字符串处理、文件查找等操作。

使用make和make clean,就可以方便地完成项目自动化构建和清理。

三、实现的原理

3.1 make/Makefile识别文件新旧

make命令不是每次都会重新编译,只有更改过的文件才会重新编译。(提高编译效率)
若源代码没有更改也重新编译,那么每次预处理编译汇编链接的时间比较长,成本高。

make/Makefile是如何知道文件更改过的?
答:通过源文件的修改时间和形成的可执行程序(也是文件)的修改时间做对比

重新编译的本质:重新写入一个二进制的可执行文件(bin文件),文件的修改时间会跟着更改。

  • 第一次的时候,一定是先有源文件,才有bin文件。
    源文件的修改时间 < bin文件的修改时间
  • 第二/n次的时候,我们对源文件做任何修改的时候,
    源文件的修改时间 > bin文件的修改时间
    ​​​​​
    重新编译形成可执行

大部分情况下重新编译都没问题,问题的产生不仅仅是修改新文件就能解决的。有些历史问题需要重新清理项目才可以解决。

文件 = 内容 + 属性,所以文件的ACM时间肯定与内容或属性有关。

Access(最近访问时间):普通文本文件打开:cat、vim,或者对目录进入、ls显示等

Modify (对内容修改):当文件内容发生变化时,修改时间(mtime)会被更新。

Change(对属性修改):当文件的权限、所有者、链接数或文件名发生变化时,更改时间(ctime)会被更新。

注:

  • 三种时间会出现联动,例如对内容修改,Access和Change时间也会更改。
  • Access时间不是每次访问时都更改,读取查看文件操作最频繁,如果每次都改的话,比较浪费时间,因为文件一般都在磁盘存放,更改时间的本质就是访问磁盘。但是访问磁盘的速度比较慢(相对cpu而言),读取查看文件操作又是很频繁,如果每次都更改Access time的话,系统效率就会降低很多,所以就会隔一段时间更改一次。
    (具体间隔时间和是否间隔,由内核版本决定)
  • 使用touch命令可以修改ACM时间。
    -a 选项  修改Access时间,但同时也修改了change时间,因为access时间也是属性。
    -m 选项 修改Modify时间,但是Change时间也会跟着改。

综上,make 是通过对比源文件和bin文件的Modify时间确定文件新旧的。

3.2 .PHONY修饰的伪目标总是被执行

通过时间对比,可以做到不让有些代码进行重新编译(不让某些操作进行)。

总是被执行就是:不考虑其他任何问题,总是执行依赖方法,不会被任何情况拦截
(make/makefile不再依靠时间对比了,直接执行对应的命令)

例如:mybin被.PHONY修饰,则多次make时,都会执行gcc命令,把可执行程序重新形成。

3.3 make/Makefile是具有依赖性的推导能力的

上一节讲到gcc编译生成一个可执行程序需要经过预处理、编译、汇编和连接,中间会产生.i,.o,.s文件。但是在上面的操作中都没有生成中间文件。
但是我们知道一件事:生成bin文件,就需要对应的.o文件。

以Makefile的推导过程如下:(类似一个栈结构)

生成了临时文件 code.o code.s code.i

以上写法只是为了了解编译推导的过程,实际上不推荐使用。

建议直接用gcc形成可执行!


四、语法技巧

  1. Makefile里面的指令执行时会自动回显出来,可以在前面加上 符号使其不回显,不显示指令信息。
  2. 可以使用 echo 添加一些输出信息。
  3. 依赖方法可以不止一个,用回车隔开。
  4. makefile中用 注释
  5. makefile中可以编写变量,表达式之间不建议带空格
    通过 $(变量名) 来引用变量的值。

    用途:之后如果想使用g++,只需要把gcc改成g++,mybin改成mybin.exe
  6. 可以用 #^ 符号代替依赖关系中的所有内容,#@ 代替要形成的目标文件

 


五、注意事项

  • 首次make时,make扫描Makefile文件时,自顶向下。如果发现第一个目标文件,则尝试根据该目标及其依赖关系构建目标文件。(默认一次形成一个最终的目标文件)
  • 伪目标文件没有实际的依赖关系,每次都会执行其定义的命令,而不是构建文件。
  • Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。
    显式规则说明了,如何生成一个或多个目标文件。
  • make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写makefile,比如源文件与目标文件之间的时间关系判断。
  • 在makefile中可以定义变量,当makefile被执行时,其中的变量都会被扩展到相应的引用位置上,通常使用 $(var) 表示引用变量。
  • 文件指示。在一个makefile中引用另一个makefile,类似C语言中的include;
    ".mk" 是用来表示 Makefile 文件的扩展名。
    include path/to/another_makefile.mktarget: dependencycommand
    
  • 注释,makefile中可以使用 # 在行首表示行注释
  • 默认的情况下,make命令会在当前目录下按顺序找寻文件名为"GNUmakefile"、"makefile"、"Makefile"的文件。

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

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

相关文章

Nginx基础篇:Nginx搭建、Nginx反向代理、文件服务器部署配置。

Nginx Linux系统安装以及反向代理的配置 简介优点nginx 环境安装常用Nginx 命令nginx 文件服务器搭建 简介 Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔赛索耶夫为俄罗斯访问量第二的Rambler.ru站点…

LabelImg的使用及注意事项

LabelImg是一款开源的图像标注工具&#xff0c;它主要用于标注目标检测、语义分割和图像分类等深度学习中需要的数据集。通过使用LabelImg&#xff0c;用户可以快速、准确地为图片中的目标添加标注信息&#xff0c;从而建立数据集。 使用步骤&#xff1a; 下载LabelImg&#x…

我的创作纪念日(2周年)

机缘 在进入大学之前&#xff0c;完全没有听说过CSDN&#xff0c;第一次使用CSDN应该是搜C语言如何学&#xff0c;或者是和C语言相关的其他内容 因为我本人是学计算机专业的&#xff0c;大一刚开学因为疫情延迟了开学时间&#xff0c;老师线上教课&#xff0c;但是我之前是完…

永磁同步电机反电动势系数怎么算?磁链强度怎么算?转矩系数怎么算?

在进行永磁同步电机simulink仿真时&#xff0c;一个关键参数就是永磁体磁链强度&#xff0c; 实际上在simulink中&#xff0c;永磁体磁链强度/反电动势系数/转矩系数这三个是放一起的&#xff0c;这是因为他们都可互相算出来。 Torque constat (Nm/A) 转矩系数 1.5 * Np *…

Tomcat部署开源站点JPress

前言 JPress使用Java开发&#xff0c;是我们常见的开源博客系统。JPress是一个开源的WordPress插件&#xff0c;它提供了一个简单而强大的方式来创建企业级站点。该插件包括许多特性&#xff0c;例如主题定制、页面构建器、性能优化、SEO、安全、电子商务和社交媒体整合等。使用…

thinkphp6入门(12)-- 一对一关联模型

定义一对一关联&#xff0c;例如&#xff0c;一个用户都有一个个人资料。 一、两表 1.用户表:user 2.工作经验表&#xff1a;work_experience user表的id关联work_experience表的user_id。 注意看&#xff0c;user_id1的有2条工作经验 二、数据模型 主表模型&#xff1a;…

STM32F407-14.3.9-02输出比较模式

输出比较模式 输出比较模式生成波形时 当采用上升沿或下降沿计数时&#xff0c;更改ARR的值可改变周期&#xff1b; 更改CCRx的值会影响到生成波形的相位。波形的占空比永远50% 当采用中心对齐模式时&#xff0c; 更改ARR的值可以改变周期&#xff0c;更改CCRx的值可以改…

操作系统考研笔记(王道408)

文章目录 前言计算机系统概述OS的基本概念OS的发展历程OS的运行机制OS体系结构OS引导虚拟机 进程和线程进程和线程基础进程进程状态进程控制进程通信线程线程实现 CPU调度调度的层次进程调度细节调度算法评价指标批处理调度算法交互式调度方法 同步与互斥基本概念互斥互斥软件实…

Plantuml之类图语法介绍(十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

STM32基于USB串口通信应用开发

✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技术同步精进&#xff0c; 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 &#x1f34e;获取更多嵌入式资料可点击链接进群领取&#xff0c;谢谢支持&#xff01;…

对无向图进行邻接矩阵的转化,并且利用DFS(深度优先)和BFS(广度优先)算法进行遍历输出, 在邻接矩阵存储结构上,完成最小生成树的操作。

一 实验目的 1&#xff0e;掌握图的相关概念。 2&#xff0e;掌握用邻接矩阵和邻接表的方法描述图的存储结构。 3&#xff0e;掌握图的深度优先搜索和广度优先搜索遍历的方法及其计算机的实现。 4&#xff0e;理解最小生成树的有关算法 二 实验内容及要求 实验内容&#…

模电·放大电路的分析方法——图解法

放大电路的分析方法——图解法 静态工作点的分析电压放大倍数的分析波形非线性失真的分析直流负载线与交流负载线图解法的适用范围 在实际测出放大管的输入特性、输出特性和已知放大电路中其它各元件参数的情况下&#xff0c;利用作图的方法对放大电路进行分析即为图解法。 静…

postgresql自带指令命令系列三

目录 简介 bin目录 28.pg_verifybackup 29.pg_waldump 30.postgres 31.postmaster -> postgres 32.psql 33.reindexdb 34.vacuumdb 35.vacuumlo 总结&#xff1a; 简介 在安装postgresql数据库的时候会需要设置一个关于postgresql数据库的PATH变量 export PATH/…

Linux CentOS 7.6安装jdk1.8教程

安装教程 第一种方式&#xff08;通过yum安装&#xff09;&#xff1a;第一步&#xff1a;输入查找命令&#xff1a;第二步&#xff1a;输入安装命令&#xff1a;第三步&#xff1a;安装完成&#xff0c;输入安装命令后&#xff0c;等到出现Complete&#xff01;代表安装完成第…

PyTorch实现逻辑回归

最终效果 先看下最终效果&#xff1a; 这里用一条直线把二维平面上不同的点分开。 生成随机数据 #创建训练数据 x torch.rand(10,1)*10 #shape(10,1) y 2*x (5 torch.randn(10,1))#构建线性回归参数 w torch.randn((1))#随机初始化w&#xff0c;要用到自动梯度求导 b …

小米手机锁屏时间设置为永不休眠_手机不息屏_保持亮屏

环境&#xff1a;打开手机自带的锁屏时间设置发现没有 永不息屏的选项 原因&#xff1a;采用了三星OLED屏幕&#xff0c;所以根据OLED屏幕特性&#xff0c;这个是为了防止烧屏而特意设计的。非OLED机型支持设置“永不” 解决方案1&#xff1a;原生系统是支持永不锁屏的&#…

ES 如何将国际标准时间格式进行格式化与调整时区

需求&#xff0c;日志收集的时候&#xff0c;时间格式是国际标准时间格式。形如yyyy-MM-ddTHH:mm:ss.SSS。 &#xff08;2023-12-05T02:45:50.282Z&#xff09;这个时区也不对&#xff0c;那如何将此类型的时间&#xff0c;进行格式化呢&#xff1f; 本篇文章体统一个案例&…

Other -- ChatGPT 原理

本文为个人理解&#xff0c;帮助小白&#xff08;本人就是&#xff09;了解正在创建新时代的 AI 产品&#xff0c;如文中理解有误欢迎留言。 [参考链接--](https://baijiahao.baidu.com/s?id1765556782543603120&wfrspider&forpc) 1. 了解一些基本概念 大语言模型&a…

【面试】测试/测开(ING)

63. APP端特有的测试 参考&#xff1a;APP专项测试、APP应用测试 crash和anr的区别 1&#xff09;网络测试 2&#xff09;中断测试 3&#xff09;安装、卸载测试 4&#xff09;兼容测试 5&#xff09;性能测试&#xff08;耗电量、流量、内存、服务器端&#xff09; 6&#xf…

画对比折线图【Python】

出这一期想必是我做某个课程作业遇到了。 由于去各个官网下载对比图要钱&#xff0c;我还是不想花钱的&#xff01;真讨厌&#xff01;浅浅水一期。 以下是要做的对比图的数据&#xff1a; 代码&#xff1a; from matplotlib import pyplot as plt#设置中文显示plt.rcParams[…