当前位置: 首页 > backend >正文

《Linux篇》自动化构建-make/Makefile

文章目录

  • 0.背景
  • 1.基本使用

在上一篇文章中,我们学习了使用gcc来编译我们的程序,但是那种方式貌似只能编译一个文件,当我们有很多源文件的时候怎么办呢?这时候就需要使用自动化构建make/Makefile了。

0.背景

  1. make是一个Linux系统内置的命令,makefile/Makefile是一个需要工程师自己构建的一个文件。两个搭配使⽤,完成项⽬⾃动化构建。
  2. ⼀个⼯程中的源⽂件不计数,其按类型、功能、模块分别放在若⼲个⽬录中,makefile定义了⼀系列的规则来指定,哪些⽂件需要先编译,哪些⽂件需要后编译,哪些⽂件需要重新编译,甚⾄于进⾏更复杂的功能操作。
  3. makefile带来的好处就是⸺“⾃动化编译”,⼀旦写好,只需要⼀个make命令,整个⼯程完全⾃动编译,极⼤的提⾼了软件开发的效率。
  4. make是⼀个命令⼯具,是⼀个解释makefile中指令的命令⼯具,⼀般来说,大多数的IDE都有这个命令,⽐如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了⼀种在⼯程⽅⾯的编译方法。

1.基本使用

code.c文件:
在这里插入图片描述
我们创建一个Makefile文件,里面的内容如下:
在这里插入图片描述
我们输入make指令就可以编译我们的程序了:
在这里插入图片描述
我们还可以在Makefile里面加入清理的功能:
在这里插入图片描述
输入make clean就可以清理掉了:
在这里插入图片描述
细节:
在这里插入图片描述
在这里插入图片描述
Q1:为什么make一下就默认的是上面的那个gcc,而make clean是下面的rm呢呢?
A1:make默认只形成一个目标,而扫描是从上往下扫描的,如何你上面的两个目标换个顺序,make就是rm和,make code才是gcc。

Q2:什么是伪目标呢?
A2:.PHONY:表示被修饰的目标是一个伪目标 -> 伪目标总是被执行的。什么叫不被执行 -> 如下图,make是不可以多次编译的,他已经是最新的了(Makefile让我们的编译工作尽可能高效一些)。如果我们给code也加上.PHONY,他就是总被执行的了。

最佳实践:可执行程序,不需要修饰为PHONY,clean修饰总是执行的。

Q3:make/makefile怎么知道我要不要重新编译呢?
A3:这就要将其我们之前学过的一个命令了:stat。.c文件和.exe都有modify时间,第一次编译完.exe的modify时间是肯定比.c文件的modify时间新的,如果.c文件一直没有修改,那也就不需要make了,而如果修改了.c文件的内容,那么他的modify时间就更新了,就可以再次make了。
在这里插入图片描述

在这里插入图片描述
一般文件内容(modify)发生改变,文件属性(change)也一定会发生改变。文件属性改变,文件内容不一定会发生改变,比如说我们chmod修改权限,只有change会修改。

Q4:为什么我们修改了文件内容,文件也被打开了,为什么access时间没有改变?
A4:现在Linux为了缓解压力,因为文件访问时间是非常频繁的,现在内核修改为访问文件多次,才会修改这个时间,这个参考意义不大。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
其实对于上面完整的make,对应的应该是如下内容:
在这里插入图片描述
在这里插入图片描述
整个流程如下:
在这里插入图片描述
这个过程是make自动推导的,这个过程其实是利用栈数据结构进行推导的:
在这里插入图片描述
完整内容如下:
在这里插入图片描述
但是我们不会这么写,一般情况下,我们都是如下的这种写法,先生成目标文件,再链接·:
在这里插入图片描述
在这里插入图片描述
扩展Makefile,我们只需要修改对应的变量名即可,每个项目都用一套相同的Makefile文件:
在这里插入图片描述
在这里插入图片描述
优化点:
在这里插入图片描述
再进一步优化:
在这里插入图片描述

http://www.xdnf.cn/news/15387.html

相关文章:

  • 自动润滑系统:从 “盲目养护“ 到智能精注的工业运维革命
  • MMaDA:多模态大型扩散语言模型
  • 动态规划题解_将一个数字表示成幂的和的方案数【LeetCode】
  • 互斥锁详解(操作系统os)
  • BERT系列模型
  • 前端工程化-构建打包
  • Flink数据流高效写入MySQL实战
  • Actor-Critic重要性采样原理
  • 九、官方人格提示词汇总(上)
  • 构造函数延伸应用
  • 数据结构 Map和Set
  • 一些git命令
  • SQL预编译:安全高效数据库操作的关键
  • Linux操作系统之信号概念启程
  • 【读书笔记】《C++ Software Design》第七章:Bridge、Prototype 与 External Polymorphism
  • IPC框架
  • [2025CVPR]GNN-ViTCap:用于病理图像分类与描述模型
  • 晋升指南-笔记
  • 【Docker基础】Dockerfile指令速览:环境与元数据指令详解
  • React强大且灵活hooks库——ahooks入门实践之状态管理类hook(state)详解
  • 【C++】多线程同步三剑客介绍
  • AutoLabor-ROS-Python 学习记录——第一章 ROS概述与环境搭建
  • leetGPU解题笔记(1)
  • STM32-第六节-TIM定时器-2(输出比较)
  • 【芯片笔记】ADF4159
  • 【论文阅读】AdaptThink: Reasoning Models Can Learn When to Think
  • 【Java Stream】基本用法学习
  • sql初学见解
  • 2025上海市“星光计划“信息安全管理与评估赛项二三阶段任务书
  • Spring高级特性——反射和动态代理的性能优化