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

Linux | makefile简单教程 | Makefile的工作原理

前言 

在学习完了Linux的基本操作之后,我们知道在linux中编写代码,编译代码都是要手动gcc命令,来执行这串代码的。

 但是我们难道在以后运行代码的时候,难道都要自己敲gcc命令嘛?这是不是有点太烦了?

 在vs中,我们编写好代码之后,直接点击构建项目,就会直接帮我们自动化构建好了,我们在linux中构建的时候,有的时候上百个文件,还是比较麻烦的,所以到底有没有一些简单的做法呢?当然是有的啦~

这个工具呢就是Makefile/make项目自动化构建工具

  • 会不会写Makefile,从一个侧面说明了一个人是否具有完成大型工程的能力;
  • 一个工程的源文件不计其数,其按类型、功能、模板分别放在一个若干个目录中,Makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作;
  • Makefile带来的好处就是——自动化编译。一旦写好,只需要一个make命令,整个工程就完成自动化编译,极大提高了软件开发的效率;
  • make是一个命令工具,是一个解释Makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,visual C++的make,linux下GNU的make。可见,Makefile都成为了一种在工程方面的编译方法。
  • make是一个命令,Makefile是一个文件,两个搭配使用,完成项目自动化构建

实例理解

 在上图中,mytest:text.cgcc -o mytest test.c是匹配的,clean:rm -f mytest是匹配的。这两组中的每个第一句是依赖关系,两组的下面称为依赖方法

Makefile实现原理

以图为例(与上图例子一致,为了方便大家查看,就在下面也放一份):

 Makefile文件写好之后,当我们实际在命令行运行make的时候,对应的make程序,会在当前目录下找这个Makefile,读取Makefile里面的内容:

  • make会根据Makefile里面的内容,完成编译、清理工作。
  • 根据Makefile里面的依赖关系,依赖关系依赖方法形成目标文件

(如上图:编译器就会知道依赖关系test.c文件形成mytest的目标文件,那么怎么形成呢?就是根据对应的gcc -o mytest test.c这样的依赖方法)

依赖关系

那么到底如何理解依赖关系依赖方法呢?

这里就给大家将一个小故事咯~便于大家理解:

小明是某大学里的在校生,这天他没有生活费了。他就打电话给那个人:“爸!我是你儿子!”在小明看来,你是我爸你就应该给我生活费;但是在老爹看来,你小子说这话是啥意思?你想干啥?老爹是一脸懵啊。小明挂了电话之后,就又想了想:“爸!我是你儿子!给我点生活费!”这下他老爹才懂了,原来他儿子没有生活费了,想要生活费。

所以在上面的小故事中,“我是你儿子”就是依赖关系,“给我点生活费”就是依赖方法。在日常生活中,我们也难免得需要拜托谁做一件什么事,在计算机中也是一样的,完成一件事的必然要素少不了依赖关系与依赖方法。

在上图中的依赖关系如下:

其实,我们知道程序翻译运行的过程为:预处理、编译、汇编和链接。

翻译的过程

gcc命令

说明

预处理

(进行宏替换)

gcc -E test.c -o test.i

-E 让gcc在预处理结束后,就停止编译

“从现在开始进行程序的翻译,预处理完成,就停下来”

宏替换

去注释

头文件展开

条件编译

生成.i文件

编译

(生成编译)

gcc -S test.i -o test.s

-S 只进行编译不进行汇编,生成汇编代码

“从现在开始进行程序的编译,汇编完成就停下来”

检查代码规范性

检查语法错误

(确认无误后汇编)

C语言代码翻译成汇编语言

生成.s文件

汇编

gcc -C test.o -o test.o

-C “从开始带现在进行程序的翻译”,汇编完成就停下来

将汇编语言编译成二进制目标文件

生成.o文件

链接

gcc test.o -o my.exe

形成可执行程序

生成.exe文件

所以将上面gcc -o mytest test.c指令写完整就是如下:

诶?很奇怪啊,怎么感觉顺序呢不太对?在这里我们就要说一下Makefile的工作原理了:

  • Makefile在执行过程中,是从上往下进行扫描的;
  • 当它看到的第一个文件时,其实并不是.c文件,第一个是.o文件;
  • 也就是识别的从上往下,第一组依赖关系;
  • 可是识别的依赖关系中的.o文件并不存在,所以它下面的命令,也就是依赖方法不能被执行,就无法形成可执行程序;
  • 所以Makefile就会自动在后续,继续再找下一组依赖关系,根据下一组依赖关系来形成.o文件;
  • 但是在形成.o文件还是需要依赖.s文件,依次类推直到遇到依赖文件存在.c文件;
  • 所以存在.c文件,就会有.i文件、.s文件以及.o文件;
  • 所以就下往上执行了,很类似与递归问题。

在上图中:

  • 上面的文件 mytest ,它依赖 mytest.o
  • mytest.o , 它依赖 mytest.s
  • mytest.s , 它依赖 mytest.i
  • mytest.i , 它依赖 mytest.c
  • make、Makefile会自动根据文件中的依赖关系,进行自动推导,帮助我们执行所有相关的依赖方法。

这里注意一下,因为Makefile就是类似于一个选择器,里面包含了各种指令的选项,但是一般默认智慧运行第一个依赖关系所对应的指令,所以上面的各组依赖关系是可以乱序的,但是必须要将最重要的一条指令放在最前面,如下图:

 上面的依赖关系,是为了让大家能够理解,这里不建议大家写成这样,直接就gcc -o mytest test.c指令就可以。

依赖文件列表

依赖文件列表可以为多个文件,按照空格分割分。

mytest:依赖文件1 依赖文件2 依赖文件3 ...

 

我们刚刚也说了clean:rm -f mytest是匹配的。根据上图我们也不难看出,clean后面是空的,也就是说clean不依赖任何文件,也就是说:

  • 依赖文件列表可以为空。 

依赖方法

依赖方法的指令前必须打一个[Tab]键,按四下空格会报错。

多条依赖方法

  • 依赖方法不限于一条,可以是多条的。 

项目清理

.PHONY含义

在Makefile文件执行的时候,如下图,我们发现在使用make的时候默认执行的是Makefile文件中的第一对的依赖关系和依赖方法:

  • Makefile默认形成第一个可执行文件。

 其次,我们看下边运行过程:

make: `mytest' is up to date. :当前可执行程序是最新的。

  • 所以Makefile会在源代码的内容没有修改,没有变化时,Makefile默认就会拦截再一次的make命令。

那么如果今天我们就想让其一直执行,不要拦截,即使在没有被修改源码的情况下,也要让make指令一直执行,那么怎么做呢?只需要:

  • .PHONY : XXX 
  • XXX对应的方法总是要被执行的。

 当然我们理解了原理之后,小编还是建议大家之后再清理的命令加上总是可执行即可。所以我们目前标准的就是以下5行:

以后我们需要的Makefile文件

通配符认识

符号含义
$^所有依赖文件列表
$@所有目标文件
$<所有依赖文件的第一个文件

 在这里,我们可以将$,理解为取内容

如下图,gcc在编译的过程,Makefile会自动进行符号替换:

  • 把对应的$@就会自动替换为目标文件
  • 把对应的$^就会自动替换为所有依赖文件

变量

Makefile也是支持变量的。但是并不是之前学习的编程语言中的整形、浮点型int/double=1/1.0等等。Makefile是解释性的,所以它的变量直接就是符号,比如说,“‘形成的可执行程序’为‘XX’”:

  • bin是“目标文件可执行程序”的变量 ;
  • src是“依赖文件列表”的变量;
  • $可以理解为去内容;
  • $(bin):取出bin变量中的内容,即目标文件;
  • $(src):取出src变量中的内容,即依赖文件列表;
  • $@:所有的目标文件;
  • $^:所有的依赖文件列表。

在执行make的时候,Makefile就会进行变量替换,可以理解成为宏的替换,也可以执行程序。

将来你可能会有很多地方遇到使用make的项目与文件,那就只需要将变量的内容修改,就可以完成不同文件的make指令进行执行,就会很简单方便。

make指令打印隐藏

在命令行输入make指令之后,系统都会自己打印出我们底层所输入的依赖方法对应的指令,那么如何将make指令进行隐藏也就是让它不再打印呢?

直接在命令前面加一个“@”符号:

推荐使用的Makefile模板

bin=test.exe    
src=test.c      @gcc -o $@ $^@echo "compiler $(src) to $(bin)..."
.PHONY:clean
clean:@rm -f $(bin)@echo "clean project..."
  • 其中echo是打印字符串。 

如下图就会有提示信息:

必熟知知识

为什么Makefile对最新的可执行程序,默认不想重新形成?

今天,我们编译的代码只有一个源文件,以后我们编译的源代码是两千个源文件,成百上千个源文件,在我们修改bug的时候,可能只是修改几行代码,做完改动之后,如果我们要将所有的源文件重新编译一遍,那么就是效率很低,又或者说,如果我们没有修改,又make的话,那么编译器又会重新编译,假如一个文件需要用0.1秒,那么成百上千个代码就需要十几分钟甚至几个小时,所以效率是极其低的。

  • 所以在Makefile为了调高效率,就默认对最新的可执行程序,不重新形成。

Makefile怎么知道程序需要被编译的呢?

ACM时间是Linux系统下分别代表AccessModifyChange三个时间。

  • Access:文件最近被访问的时间(访问)
  • Modify : 文件内容最近被修改的时间(修改)
  • Change : 文件属性最近被修改的时间(改变)

当然我们要知道的是:

  • 源代码可执行程序文件内容最近被修改的时间(修改)一定是不同的。 

因为我们基本先写源代码,再进行编译;所以可执行程序一般是比源代码的时间更新的。如果修改的源代码,那么此时源代码比可执行程序的时间更新,所以就需要重新编译。

Makefile怎么知道程序需要被编译的呢?

  • 对比可执行程序的最近修改时间和源文件最近的修改时间,谁更新。如果可执行程序更新,就不需要重新编译了;反之,源文件更新,就需要重新编译。

所以我们在用vs写代码的时候,出现错误 ,再修改了很多次,仍旧报这个错误,这个时候,可以重新清理一下,重新构建一下,重新生成解决方案,这个问题就会可能解决。

相关文章:

Linux | makefile简单教程 | Makefile的工作原理

前言 在学习完了Linux的基本操作之后&#xff0c;我们知道在linux中编写代码&#xff0c;编译代码都是要手动gcc命令&#xff0c;来执行这串代码的。 但是我们难道在以后运行代码的时候&#xff0c;难道都要自己敲gcc命令嘛&#xff1f;这是不是有点太烦了&#xff1f; 在vs中…...

pcl+vtk(十四)vtkCamera相机简单介绍

一、vtkCamera相机 人眼相当于三维场景下的相机&#xff0c; VTK是用vtkCamera类来表示三维渲染场景中的相机。vtkCamera负责把三维场景投影到二维平面&#xff0c;如屏幕、图像等。 相机位置&#xff1a;即相机所在的位置&#xff0c;用方法vtkCamera::SetPosition()设置。 相…...

TS基础知识点快速回顾(上)

基础介绍 什么是 TypeScript&#xff1f; TypeScript&#xff0c;简称 ts&#xff0c;是微软开发的一种静态的编程语言&#xff0c;它是 JavaScript 的超集。 那么它有什么特别之处呢? js 有的 ts 都有&#xff0c;所有js 代码都可以在 ts 里面运行。ts 支持类型支持&#…...

hook(post-receive)无法使用

hook&#xff08;post-receive&#xff09;无法使用 为什么无法使用&#xff1f; 只有一个问题&#xff1a;权限不够&#xff0c;你想想&#xff0c;blog.git是一个中转站&#xff0c;咱们要把上传的东西转到blog下面&#xff0c;肯定要有写入操作呀&#xff0c;这个Git仓库的…...

qt学习:tcp区分保存多个客户端

在前面文掌的tcp客服端服务端进行更改 qt学习&#xff1a;Network网络类tcp客户端tcp服务端-CSDN博客https://blog.csdn.net/weixin_59669309/article/details/135842933?spm1001.2014.3001.5501前面的服务端每次有新的客户端连接&#xff0c;就会覆盖掉原来的指针&#xff0…...

ORM-08-EclipseLink 入门介绍

拓展阅读 The jdbc pool for java.(java 手写 jdbc 数据库连接池实现) The simple mybatis.&#xff08;手写简易版 mybatis&#xff09; 1. EclipseLink概述 本章介绍了EclipseLink及其关键特性&#xff1a;包括在EclipseLink中的组件、元数据、应用程序架构、映射和API。 本…...

数据结构之树和二叉树定义

数据结构之树和二叉树定义 1、树的定义2、树的基本概念3、二叉树的定义 数据结构是程序设计的重要基础&#xff0c;它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发&#xff0c;分析和研究计算机加工的数据的特性&#xff0c;以…...

大模型学习与实践笔记(十三)

将训练好的模型权重上传到 OpenXLab 方式1&#xff1a; 先将Adapter 模型权重通过scp 传到本地&#xff0c;然后网页上传 步骤1. scp 到本地 命令为&#xff1a; scp -o StrictHostKeyCheckingno -r -P *** rootssh.intern-ai.org.cn:/root/data/ e/opencv/ 步骤2&#…...

计算机网络——网络层(1)

计算机网络——网络层(1&#xff09; 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU) 网络层&#xff1a;数据平面网络层概述核心功能协议总结 路由器工作原理路由器的工作步骤总结 网际协议IPv4主要特点不足IPv6主要特点现状 通用转发和SDN通用转发SDN&#xff08;软件…...

解释LoRA参数

目录 LoRA参数含义 LoRA在深度学习中的作用 示例代码中的LoRA应用 结论 LoRA参数含义 LoRA (lora_r): LoRA代表"Low-Rank Adaptation"&#xff0c;是一种模型参数化技术&#xff0c;用于在不显著增加参数数量的情况下调整预训练模型。lora_r参数指的是LoRA中的秩&…...

直播核心岗位基础内容

一.直播间核心岗位 1.直播间前端岗位 前端岗位分工 &#xff08;1&#xff09;主播岗位职责 &#xff08;2&#xff09;场控岗位职责 &#xff08;3&#xff09;助理岗位职责 中端岗位分工 &#xff08;1&#xff09;运营岗位职责 &#xff08;2&#xff09;中控岗位职责 …...

安全防御第三次作业

作业&#xff1a;拓扑图及要求如下图 注&#xff1a;server1是ftp服务器&#xff0c;server2是http服务器 lsw1&#xff1a; 其中g0/0/0口为trunk 实现 1&#xff0c;生产区在工作时间内可以访问服务器区&#xff0c;仅可以访问http服务器 验证&#xff1a; 2&#xff0c;办公…...

WordPress反垃圾评论插件Akismet有什么用?如何使用Akismet插件?

每次我们成功搭建好WordPress网站后&#xff0c;都可以在后台 >> 插件 >> 已安装的插件&#xff0c;在插件列表中可以看到有一个“Akismet反垃圾邮件&#xff1a;垃圾邮件保护”的插件&#xff08;个人觉得是翻译错误&#xff0c;应该是反垃圾评论&#xff09;。具…...

力扣80、删除有序数组中的重复项Ⅱ(中等)

1 题目描述 图1 题目描述 2 题目解读 对于有序数组nums&#xff0c;要求在不使用额外数组空间的条件下&#xff0c;删除数组nums中重复出现的元素&#xff0c;使得nums中出现次数超过两次的元素只出现两次。返回删除后数组的新长度。 3 解法一&#xff1a;双指针 双指针法可以…...

探索HTMLx:强大的HTML工具

1. HTMLX htmx 是一个轻量级的 JavaScript 库&#xff0c;它允许你直接在 HTML 中使用现代浏览器的功能&#xff0c;而不需要编写 JavaScript 代码。通过 htmx&#xff0c;你可以使用 HTML 属性执行 AJAX 请求&#xff0c;使用 CSS 过渡动画&#xff0c;利用 WebSocket 和服务…...

NC65中间件能启动,前端客户端启动失败,加载异常,卡住(org.owasp.esapi)

控制台输出错误 ESAPI.properties could not be loaded by any means. Fail.SecurityConfiguration class(org.owasp.esapi.reference.DefaultSecurityConfiguration) CTOR threw exception.效果图&#xff1a; 解决方案 添加如下参数&#xff1a; -Dorg.owasp.esapi.resou…...

【大数据】YARN调度器及调度策略

YARN调度器 YARN负责作业资源调度&#xff0c;在集群中找到满足业务的资源&#xff0c;帮助作业启动任务&#xff0c;管理作业的生命周期。 ​ YARN技术架构 ​ 目前&#xff0c;Hadoop作业调度器主要有三种&#xff1a;先进先出调度器&#xff08;First In First Out&…...

如何快速入门Python指南

在数字化时代&#xff0c;掌握一门编程语言已成为众多行业和职业必备的技能之一。Python以其简洁易读的语法、丰富的库资源以及强大的跨领域应用能力&#xff0c;成为了初学者学习编程的理想选择。本文旨在为新手提供一套全面且深入的Python学习路径&#xff0c;并结合实践建议…...

vue3 页面长时间不使用,再次点击页面切换路由 操作无效报错

问题描述: 使用Vite打包构建的项目&#xff0c;重新部署到生产。在部署期间用户一直停留在当前项目页面&#xff08;长时间无操作 半个小时&#xff09;&#xff0c;部署完成后点击页面上的路由&#xff0c;报错&#xff01; 刷新后恢复正常。出现问题原因&#xff1a; 上线打…...

【算法练习】leetcode算法题合集之动态规划篇

普通动规系列 LeetCode343. 整数拆分 LeetCode343. 整数拆分 将10的结果存在索引为10的位置上&#xff0c;需要保证数组长度是n1&#xff0c;索引的最大值是n&#xff0c;索引是从0开始的。 n的拆分&#xff0c;可以拆分为i和n-i&#xff0c;当然i可以继续拆分。而且拆分为n-…...

青少年人工智能实验基地解决方案

1. 方案背景 1.1人工智能创新教育解决方案背景 人工智能已成为引领未来的新兴技术&#xff0c;中国将人工智能列为国家重点发展战略&#xff0c;对人工智能的发展做出了总体部署&#xff0c;全面加速人工智能在研发应用和人才培养的步伐。2021年1月教育部官网公布《关于政协十…...

10个让你的明星网红推广事半功倍的技巧-华媒舍

明星网红已成为市场推广和品牌宣传的重要方式。要在竞争激烈的市场中脱颖而出&#xff0c;并吸引更多的观众和粉丝&#xff0c;需要一些科学而有效的技巧。本文将向你介绍10个让你的明星网红推广事半功倍的技巧。 技巧一&#xff1a;建立个人品牌 成功的明星网红通常都有独特而…...

k8s集群异常恢复

前提、我自己的k8s采用的是单master节点两个从节点部署&#xff0c;我针对单master情况进行恢复说明 场景一&#xff1a;正常开关虚拟机&#xff0c;可直接重启kubelet进行恢复 1、1、一般重启后三个节点都需要检查&#xff0c;输入命令检查kubelet&#xff1a; systemctl s…...

NOC总线(2)

1. NoC的路由 在NoC交换信息时&#xff0c;需要确定从源节点到目标节点所经过的路径&#xff0c;这时就需要路由算法来确定该路径。路由算法分为静态路由算法和动态路由算法两种。 静态路由算法对于两节点之间的路径是固定的&#xff0c;结构简单&#xff0c;便于硬件实…...

2401llvm,clang的libtooling

LibTooling(库工具) LibTooling是个支持基于Clang编写独立工具的库. 在此,为LLVM安装Clang工具 介绍 用LibTooling构建的工具(如Clang插件)通过代码运行FrontendActions. 这里演示运行Clang的快速检查一堆代码语法的SyntaxOnlyAction的不同方法. 解析内存中的代码片 如果想…...

数据结构—基础知识(13):树的存储结构

数据结构—基础知识&#xff08;13&#xff09;&#xff1a;树的存储结构 双亲表示法 这种表示方法中&#xff0c;以一组连续的存储单元存储树的结点&#xff0c;每个结点除了数据域data外&#xff0c;还附设一个parent域用以指示其双亲结点的位置。 这种存储结构利用了每个结…...

【Python爬虫入门到精通】小白也能看懂的知识要点与学习路线

文章目录 1. 写在前面2. 爬虫行业情况3. 学习路线 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感兴趣的朋友可以关…...

服务器数据恢复—EVA存储raid5硬盘离线的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌EVA某型号存储&#xff0c;底层是RAID5阵列&#xff0c;划分了若干lun。 服务器故障&分析&#xff1a; 该存储设备中raid5阵列有两块硬盘掉线&#xff0c;存储中的lun丢失。 将故障服务器存储中的所有磁盘编号后取出&#xff0c;硬件…...

MAMBA论文疑被拒收,计算机科学顶会评审遭质疑

2023 年底&#xff0c;卡内基梅隆和普林斯顿大学计算机系的两位年轻科学家&#xff08;Albert Gu, Tri Dao&#xff09;联合推出一种叫做“Mamba”的大语言模型&#xff08;LLM&#xff09;新构架。与Transformers等传统模型相比&#xff0c;Mamba能够更有效地处理长序列。它利…...

EHS管理系统为何需要物联网的加持?

EHS是Environment、Health、Safety的缩写&#xff0c;是从欧美企业引进的管理体系&#xff0c;在国外也被称为HSE。EHS是指健康、安全与环境一体化的管理。 而在国内&#xff0c;整个EHS市场一共被分成三类&#xff1b; 一类是EHS管培体系&#xff0c;由专门的EHS机构去为公司…...

汕头做网站设计/如何推广app让别人注册

无意中看到别人的网站上有 rssdatasource 不知道是干嘛的 于是去网上baidu 才知道 做网站 可以省下力气了 记下来 怕以后会忘记...

个人网站建设策划书/怎么做一个网页

以下内容均为网络上整理的资料 一.链接是什么? 我们在这里可以去引用csapp 的定义 : 链接&#xff08;linking&#xff09;是将各种代码和数据部分收集起来并组合成为一个单一文件的过程&#xff0c;这个文件可被加载&#xff08;或被拷贝&#xff09;到存储器并执行。 了解…...

网站建设php招聘/免费推广网站排行榜

最小均方误差&#xff08;MMSE&#xff09;意义下的最优帧内预测推导&#xff1a; MMSE:Minimum Mean Squared Error,思想是将预测值和真值的误差的平方的期望&#xff08;均值&#xff09;最小化&#xff0c;以使得预测值尽量逼近真值&#xff0c;和真值差距尽可能小&#xff…...

网站建设案例资料/百度网址大全下载安装

【题目背景】 于万人中万幸得以相逢&#xff0c;刹那间澈净明通。 成为我所向披靡的勇气和惶恐&#xff0c;裂山海&#xff0c;堕苍穹。 爱若执炬迎风&#xff0c;炽烈而哀恸&#xff0c;诸般滋味皆在其中。 韶华宛转吟诵&#xff0c;苍凉的光荣&#xff0c;急景凋年深情难共。…...

汽车网站制作/今日头条新闻最全新消息

在上一篇文章中&#xff0c;我们分析了Android系统进程间通信机制Binder中的Server在启动过程使用Service Manager的addService接口把自己添加到Service Manager守护过程中接受管理。在这一篇文章中&#xff0c;我们将深入到Binder驱动程序源代码去分析Client是如何通过Service…...

可以做微课PPT模板 网站/百度关键词热度排名

一.自定义指令directive 除了核心功能默认内置的指令 (v-model 和 v-show)&#xff0c;Vue 也允许注册自定义指令。注意&#xff0c;在 Vue2.0 中&#xff0c;代码复用和抽象的主要形式是组件。然而&#xff0c;有的情况下&#xff0c;你仍然需要对普通 DOM 元素进行底层操作&a…...