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.c与gcc -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系统下分别代表Access,Modify和Change三个时间。
- Access:文件最近被访问的时间(访问)
- Modify : 文件内容最近被修改的时间(修改)
- Change : 文件属性最近被修改的时间(改变)
当然我们要知道的是:
- 源代码与可执行程序的文件内容最近被修改的时间(修改)一定是不同的。
因为我们基本先写源代码,再进行编译;所以可执行程序一般是比源代码的时间更新的。如果修改的源代码,那么此时源代码比可执行程序的时间更新,所以就需要重新编译。
Makefile怎么知道程序需要被编译的呢?
- 对比可执行程序的最近修改时间和源文件最近的修改时间,谁更新。如果可执行程序更新,就不需要重新编译了;反之,源文件更新,就需要重新编译。
所以我们在用vs写代码的时候,出现错误 ,再修改了很多次,仍旧报这个错误,这个时候,可以重新清理一下,重新构建一下,重新生成解决方案,这个问题就会可能解决。
相关文章:
Linux | makefile简单教程 | Makefile的工作原理
前言 在学习完了Linux的基本操作之后,我们知道在linux中编写代码,编译代码都是要手动gcc命令,来执行这串代码的。 但是我们难道在以后运行代码的时候,难道都要自己敲gcc命令嘛?这是不是有点太烦了? 在vs中…...
pcl+vtk(十四)vtkCamera相机简单介绍
一、vtkCamera相机 人眼相当于三维场景下的相机, VTK是用vtkCamera类来表示三维渲染场景中的相机。vtkCamera负责把三维场景投影到二维平面,如屏幕、图像等。 相机位置:即相机所在的位置,用方法vtkCamera::SetPosition()设置。 相…...
TS基础知识点快速回顾(上)
基础介绍 什么是 TypeScript? TypeScript,简称 ts,是微软开发的一种静态的编程语言,它是 JavaScript 的超集。 那么它有什么特别之处呢? js 有的 ts 都有,所有js 代码都可以在 ts 里面运行。ts 支持类型支持&#…...
hook(post-receive)无法使用
hook(post-receive)无法使用 为什么无法使用? 只有一个问题:权限不够,你想想,blog.git是一个中转站,咱们要把上传的东西转到blog下面,肯定要有写入操作呀,这个Git仓库的…...
qt学习:tcp区分保存多个客户端
在前面文掌的tcp客服端服务端进行更改 qt学习:Network网络类tcp客户端tcp服务端-CSDN博客https://blog.csdn.net/weixin_59669309/article/details/135842933?spm1001.2014.3001.5501前面的服务端每次有新的客户端连接,就会覆盖掉原来的指针࿰…...
ORM-08-EclipseLink 入门介绍
拓展阅读 The jdbc pool for java.(java 手写 jdbc 数据库连接池实现) The simple mybatis.(手写简易版 mybatis) 1. EclipseLink概述 本章介绍了EclipseLink及其关键特性:包括在EclipseLink中的组件、元数据、应用程序架构、映射和API。 本…...
数据结构之树和二叉树定义
数据结构之树和二叉树定义 1、树的定义2、树的基本概念3、二叉树的定义 数据结构是程序设计的重要基础,它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发,分析和研究计算机加工的数据的特性,以…...
大模型学习与实践笔记(十三)
将训练好的模型权重上传到 OpenXLab 方式1: 先将Adapter 模型权重通过scp 传到本地,然后网页上传 步骤1. scp 到本地 命令为: scp -o StrictHostKeyCheckingno -r -P *** rootssh.intern-ai.org.cn:/root/data/ e/opencv/ 步骤2&#…...
计算机网络——网络层(1)
计算机网络——网络层(1) 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU) 网络层:数据平面网络层概述核心功能协议总结 路由器工作原理路由器的工作步骤总结 网际协议IPv4主要特点不足IPv6主要特点现状 通用转发和SDN通用转发SDN(软件…...
解释LoRA参数
目录 LoRA参数含义 LoRA在深度学习中的作用 示例代码中的LoRA应用 结论 LoRA参数含义 LoRA (lora_r): LoRA代表"Low-Rank Adaptation",是一种模型参数化技术,用于在不显著增加参数数量的情况下调整预训练模型。lora_r参数指的是LoRA中的秩&…...
直播核心岗位基础内容
一.直播间核心岗位 1.直播间前端岗位 前端岗位分工 (1)主播岗位职责 (2)场控岗位职责 (3)助理岗位职责 中端岗位分工 (1)运营岗位职责 (2)中控岗位职责 …...
安全防御第三次作业
作业:拓扑图及要求如下图 注:server1是ftp服务器,server2是http服务器 lsw1: 其中g0/0/0口为trunk 实现 1,生产区在工作时间内可以访问服务器区,仅可以访问http服务器 验证: 2,办公…...
WordPress反垃圾评论插件Akismet有什么用?如何使用Akismet插件?
每次我们成功搭建好WordPress网站后,都可以在后台 >> 插件 >> 已安装的插件,在插件列表中可以看到有一个“Akismet反垃圾邮件:垃圾邮件保护”的插件(个人觉得是翻译错误,应该是反垃圾评论)。具…...
力扣80、删除有序数组中的重复项Ⅱ(中等)
1 题目描述 图1 题目描述 2 题目解读 对于有序数组nums,要求在不使用额外数组空间的条件下,删除数组nums中重复出现的元素,使得nums中出现次数超过两次的元素只出现两次。返回删除后数组的新长度。 3 解法一:双指针 双指针法可以…...
探索HTMLx:强大的HTML工具
1. HTMLX htmx 是一个轻量级的 JavaScript 库,它允许你直接在 HTML 中使用现代浏览器的功能,而不需要编写 JavaScript 代码。通过 htmx,你可以使用 HTML 属性执行 AJAX 请求,使用 CSS 过渡动画,利用 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.效果图: 解决方案 添加如下参数: -Dorg.owasp.esapi.resou…...
【大数据】YARN调度器及调度策略
YARN调度器 YARN负责作业资源调度,在集群中找到满足业务的资源,帮助作业启动任务,管理作业的生命周期。 YARN技术架构 目前,Hadoop作业调度器主要有三种:先进先出调度器(First In First Out&…...
如何快速入门Python指南
在数字化时代,掌握一门编程语言已成为众多行业和职业必备的技能之一。Python以其简洁易读的语法、丰富的库资源以及强大的跨领域应用能力,成为了初学者学习编程的理想选择。本文旨在为新手提供一套全面且深入的Python学习路径,并结合实践建议…...
vue3 页面长时间不使用,再次点击页面切换路由 操作无效报错
问题描述: 使用Vite打包构建的项目,重新部署到生产。在部署期间用户一直停留在当前项目页面(长时间无操作 半个小时),部署完成后点击页面上的路由,报错! 刷新后恢复正常。出现问题原因: 上线打…...
【算法练习】leetcode算法题合集之动态规划篇
普通动规系列 LeetCode343. 整数拆分 LeetCode343. 整数拆分 将10的结果存在索引为10的位置上,需要保证数组长度是n1,索引的最大值是n,索引是从0开始的。 n的拆分,可以拆分为i和n-i,当然i可以继续拆分。而且拆分为n-…...
青少年人工智能实验基地解决方案
1. 方案背景 1.1人工智能创新教育解决方案背景 人工智能已成为引领未来的新兴技术,中国将人工智能列为国家重点发展战略,对人工智能的发展做出了总体部署,全面加速人工智能在研发应用和人才培养的步伐。2021年1月教育部官网公布《关于政协十…...
10个让你的明星网红推广事半功倍的技巧-华媒舍
明星网红已成为市场推广和品牌宣传的重要方式。要在竞争激烈的市场中脱颖而出,并吸引更多的观众和粉丝,需要一些科学而有效的技巧。本文将向你介绍10个让你的明星网红推广事半功倍的技巧。 技巧一:建立个人品牌 成功的明星网红通常都有独特而…...
k8s集群异常恢复
前提、我自己的k8s采用的是单master节点两个从节点部署,我针对单master情况进行恢复说明 场景一:正常开关虚拟机,可直接重启kubelet进行恢复 1、1、一般重启后三个节点都需要检查,输入命令检查kubelet: systemctl s…...
NOC总线(2)
1. NoC的路由 在NoC交换信息时,需要确定从源节点到目标节点所经过的路径,这时就需要路由算法来确定该路径。路由算法分为静态路由算法和动态路由算法两种。 静态路由算法对于两节点之间的路径是固定的,结构简单,便于硬件实…...
2401llvm,clang的libtooling
LibTooling(库工具) LibTooling是个支持基于Clang编写独立工具的库. 在此,为LLVM安装Clang工具 介绍 用LibTooling构建的工具(如Clang插件)通过代码运行FrontendActions. 这里演示运行Clang的快速检查一堆代码语法的SyntaxOnlyAction的不同方法. 解析内存中的代码片 如果想…...
数据结构—基础知识(13):树的存储结构
数据结构—基础知识(13):树的存储结构 双亲表示法 这种表示方法中,以一组连续的存储单元存储树的结点,每个结点除了数据域data外,还附设一个parent域用以指示其双亲结点的位置。 这种存储结构利用了每个结…...
【Python爬虫入门到精通】小白也能看懂的知识要点与学习路线
文章目录 1. 写在前面2. 爬虫行业情况3. 学习路线 【作者主页】:吴秋霖 【作者介绍】:Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作! 【作者推荐】:对JS逆向感兴趣的朋友可以关…...
服务器数据恢复—EVA存储raid5硬盘离线的数据恢复案例
服务器数据恢复环境: 某品牌EVA某型号存储,底层是RAID5阵列,划分了若干lun。 服务器故障&分析: 该存储设备中raid5阵列有两块硬盘掉线,存储中的lun丢失。 将故障服务器存储中的所有磁盘编号后取出,硬件…...
MAMBA论文疑被拒收,计算机科学顶会评审遭质疑
2023 年底,卡内基梅隆和普林斯顿大学计算机系的两位年轻科学家(Albert Gu, Tri Dao)联合推出一种叫做“Mamba”的大语言模型(LLM)新构架。与Transformers等传统模型相比,Mamba能够更有效地处理长序列。它利…...
EHS管理系统为何需要物联网的加持?
EHS是Environment、Health、Safety的缩写,是从欧美企业引进的管理体系,在国外也被称为HSE。EHS是指健康、安全与环境一体化的管理。 而在国内,整个EHS市场一共被分成三类; 一类是EHS管培体系,由专门的EHS机构去为公司…...
汕头做网站设计/如何推广app让别人注册
无意中看到别人的网站上有 rssdatasource 不知道是干嘛的 于是去网上baidu 才知道 做网站 可以省下力气了 记下来 怕以后会忘记...
个人网站建设策划书/怎么做一个网页
以下内容均为网络上整理的资料 一.链接是什么? 我们在这里可以去引用csapp 的定义 : 链接(linking)是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(或被拷贝)到存储器并执行。 了解…...
网站建设php招聘/免费推广网站排行榜
最小均方误差(MMSE)意义下的最优帧内预测推导: MMSE:Minimum Mean Squared Error,思想是将预测值和真值的误差的平方的期望(均值)最小化,以使得预测值尽量逼近真值,和真值差距尽可能小ÿ…...
网站建设案例资料/百度网址大全下载安装
【题目背景】 于万人中万幸得以相逢,刹那间澈净明通。 成为我所向披靡的勇气和惶恐,裂山海,堕苍穹。 爱若执炬迎风,炽烈而哀恸,诸般滋味皆在其中。 韶华宛转吟诵,苍凉的光荣,急景凋年深情难共。…...
汽车网站制作/今日头条新闻最全新消息
在上一篇文章中,我们分析了Android系统进程间通信机制Binder中的Server在启动过程使用Service Manager的addService接口把自己添加到Service Manager守护过程中接受管理。在这一篇文章中,我们将深入到Binder驱动程序源代码去分析Client是如何通过Service…...
可以做微课PPT模板 网站/百度关键词热度排名
一.自定义指令directive 除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作&a…...