Makefile的使用 和 基本语法 及Makefile中变量的使用【入门必看】

news2024/11/18 15:51:41

Makefile

  • Makefile概要
  • 为啥要使用Makefile
  • Makefile的使用
  • Makefile的语法(重点)
  • Makefile实际使用(重点)
    • 利用Makefile删除
    • 详解Makefile指令(重点)
    • Makefile多命令选项
    • Makefile的选择编译特性
    • 强制执行
    • 总结
    • Makefile中变量的使用

Makefile概要

Makefile是一个文件,他是一个工程文件的编译规则。好的Makefile文件可以使用一行命令来完成“自动化编译”,极大提高工作效率。

为啥要使用Makefile

假设我这有两个源代码文件main.c 及 myadd.c,需将其两个编译成一个可执行程序,因为main.c 中调用了 myadd.c中的函数。

正常我们会向下图一样先gcc -c myadd.c -o myadd.o 使其形成汇编代码 。再gcc myadd.o main.c -o a.out 使其两个源文件编译并链接起来形成可执行程序
在这里插入图片描述
从上图可以看出两个源文件一起编译形成可执行程序需要两步,并且指令较长。当我们遇到几个甚至几十个源文件一起编译时这将是一个令人头疼的苦差,中途还可能把指令输错。

Makefile的使用

这时候Makefile的作用就体现出来了,我们先在要编译的源文件目录下建立一个Makefile文件(注意不是目录)
操作如下:
请添加图片描述
然后再用文本编辑器在Makefile文件中写好指令,在这我用的是vim。如下图在文件中写好指令(现在先不用知道为啥先跟着打上一会会解释)
在这里插入图片描述
写好后保存并退出vim,在命令行输入make程序就能自动编译了,非常方便快捷。
请添加图片描述

Makefile的语法(重点)

如下图假设我们要用Makefile工具,编译main.c
在这里插入图片描述
如上图(我已经提前创建好了)先在要编译的源文件目录下建立一个Makefile文件(注意不是目录)
在编辑Makefile前我们应该定三个前提
1:最终要形成的目标文件名
2:目标文件由什么文件编译得来
3:编译命令是什么

并且Makefile基本规则如下

要形成目标文件名 :源文件
<tob> 命令

实际解释如下图,main 是要形成的目标文件main,main.c 是源文件(也被称为main 的依赖文件),gcc -o main main.c是命令,并且语法规定命令前必须以 tob键 开头
在这里插入图片描述
编辑完成后保存并退出即可,在命令行输入make即可自动编译
请添加图片描述

Makefile实际使用(重点)

在实际中,我们可能会遇到多个源文件一起编译的情况。下面演示用Makefile工具编译三个源文件,更多的情况也是同一个思路大家放心。

假设我的三个源文件分别是以下三个

main.c

#include"my.h"
int main()
{
  int i = add(3,6);
  print(i);
  return 0;
}

add.c

#include"my.h"

int add(int x , int y)
{
  return x + y ;
}

print.c

#include"my.h"

void print(int x)
{
  printf("%d\n",x);
}

要用Makefile编译这三个源文件,首先思想是先让这三个源文件都形成汇编代码后再将其链接起来,gcc中 -E是预编译选项,-S是编译选项,-c是汇编选项。这里我们需要得到汇编所以用到 -c 选项链接直接gcc 及所有要连接代码即可

确定思想后我们开始编辑Makefile如下
在这里插入图片描述
Makefile也是自上而下读取数据的,但执行顺序可能不同。
比如上图编译三个源代码时由于第一条,需要具有main.o print.o add.o三个文件才能编译成a.out文件(目标文件是main.o,源文件是main.o print.o add.o)显然这个条件并不满足。所以Makefile会先把第一条指令保存起来先执行下面已经满足条件的代码直到条件满足时才会执行(具有main.o print.o add.o三个文件)

第二条指令,要求文件中有main.c文件,显然我们是满足条件的,所以执行了gcc -c main.c -o main.o命令,同时也生成了main.o文件

第三条指令,要求文件中有print.c文件,显然我们是满足条件的,所以执行了gcc -c print.c -o print.o命令,同时也生成了print.o文件

第四条指令,要求文件中有add.c文件,显然我们是满足条件的,所以执行了gcc -c add.c -o add.o命令,同时也生成了add.o文件

这个时候我们显然已经满足了第一条指令的要求,有了main.o print.o add.o三个文件。所以执行gcc main.o add.o print.o -o a.out命令并生成了a.out文件

注意:如果Makefil文件中其他指令都执行完了依然有一条指令不满足条件而无法执行,Makefile将会报错,说明指令的依赖关系设置有误

成果演示:
请添加图片描述

利用Makefile删除

读完上述内容已经可以利用Makefile实现自动编译了,但是编译过程中产生了汇编文件main.o print.o add.o,我只想要最终的啊a.out文件。所以每次编译后我需要一一删除异常麻烦。

其实Makefile能设置很多功能,其中实现自动删除目标文件也是不在话下的
只要我们在Makefile加上
clean:
rm main.o print.o add.o

即可。
在这里插入图片描述
保存并退出后 ,命令行输入Makefile clean即可删除main.o print.o add.o三个文件
请添加图片描述

详解Makefile指令(重点)

有人看到这肯定说,为啥编译用make作为指令,删除用make clean作为指令

其实make命令是默认执行Makefile文件中的第一条指令,及其相关指令。

比如我把Makefile中代码换一下,执行大家就明白了
在这里插入图片描述
代码更改后我们依然输入make,但这次只生成了main.o文件说明只执行了Makefile中的第一行代码。
请添加图片描述
上面已经证实了make命令是默认执行Makefile文件中的第一条指令,然后Makefile的命令规则为

make [命令选项]

命令选项是目标文件名,虽然clean不会生成文件但我们也可以把他看做成目标文件名
如下图框框中的都是命令选项
在这里插入图片描述
实际使用
如下动图我演示了指令有
1:make add.o
2: make print.o
3: make main.o
4: make clean
5: make a.out
动图较长大家忍一下
请添加图片描述

Makefile多命令选项

并且可以同时有多条命令选项
如: make a.out clean
作用:(在我这个Makefile下)执行a.out选项命令编译链接完代码后,执行clean选项命令(把不需要的汇编代码删除);
如下图
在这里插入图片描述
上述说明Makefile非常强大,可以有很多条编译指令,并且互不影响。

Makefile的选择编译特性

在实际工程中代码的编译时间通常比较长,如果重复性编译这会浪费很多时间。所以Makefile在编译前都会检查代码较上次编译是否发生过更改,如果没有将不会编译次代码,如下图。
在这里插入图片描述

如下图,在多文件编译中,Makefile依然只会编译修改后的源文件,未修改的并不会重新编译,这大大节省了编译时间(如果是几十个源文件甚至更多的工程呢,仅仅是区分就令人头疼了)
在这里插入图片描述

强制执行

上面说了Makefile是有自己想法的,可以选择性编译(执行)。
但我就想他每次必须执行,我不需要他又想法。那使用 .PHONY 修饰即可
如下图
在这里插入图片描述
如下图加完之后,就能每次都执行了(强制),不会出现选择性执行的情况。
在这里插入图片描述

总结

1:命令行必须以键开通
2:目标文件与依赖文件之间需以 :号隔开
3:Makefile能有多条指令
4:Makefile编译完成后,后期有代码更新Makefike能针对被修改的源文件单独编译并链接。

Makefile中变量的使用

如下图main.o print.o add.o比较长,每次都要打比较繁琐。
针对这个问题Makefile可以定义变量来简化他,比如下图使DATA 等于main.o print.o add.o
定义方法:变量名 = 字符串(各文件名等)
使用方法:${变量名}
在这里插入图片描述
使用效果
在这里插入图片描述
优点:变量的定义能简化复杂且重复的数据使代码美观,编写方便。
变量的基本语法
1.变量与变量内容以= 号隔开,同时两边可以具有空格

2.变量左边不可以有,例如上面范例的第一行DATA左边不可以是

3.变量与变量内容在 = 号两边不能具有 : 号

4.在习惯上,变量名最好是以大写字母为主;

5.运用变量时,以 变量或 {变量}或 变量 (变量)使用;

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

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

相关文章

使用 Keras 深度学习库进行CNN 图像识别

Keras 是一个用于深度学习的 Python 库&#xff0c;它封装了强大的数值库 Theano 和 TensorFlow。 在本文中&#xff0c;你将了解如何在 Keras 中开发和评估用于图像识别的深度学习模型。完成本文后&#xff0c;你将了解&#xff1a; 关于 CIFAR-10 对象分类数据集以及如何在…

Pyrene-PEG5-propargyl_1817735-33-3_芘甲酰胺五聚乙二醇丙炔

Pyrene-PEG5-propargyl&#xff0c;芘甲酰胺-五聚乙二醇-丙炔Product structure&#xff1a;Pyrene-PEG5-propargyl结构式Product specifications&#xff1a;1.CAS No&#xff1a;1817735-33-32.Molecular formula&#xff1a;C30H33NO63.Molecular weight&#xff1a;503.64.…

一文弄懂三色标记算法

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 你愈是少说你的伟大&#xff0c;我将愈想到你的伟大。——培根 文章目录三色标记算法增量更新原始快照面试官&#xff1a;我们先从JVM基础开始问&#xff0c;了解三色标记算法吗&#xff1f;我&#xff1a;额…

CSS或JS实现逐帧动画方案

什么是逐帧动画 逐帧动画是一种在连续的关键帧中分解动画动作&#xff0c;即在时间轴的每一帧上绘制不同内容并使之连续播放成动画的一种常见的动画形式。与CSS关键帧动画不同的是&#xff0c;逐帧动画每一帧需要自行定义&#xff1b;关键帧动画只需定义部分关键帧&#xff0c;…

《机会成本》的阅读札记

【引子】第一次接触机会成本&#xff0c;大约还是十几年前自己在读MBA的时候&#xff0c;在徐华老师《管理经济学》的课上听到过一耳朵&#xff0c;但没有太多的认知。这个春节&#xff0c;阅读了《机会成本——做出高效决策的策略思维》才有了些许进一步的认识&#xff0c;那么…

从0到1介绍一下开源大数据服务平台dataService

1.背景&现状 在大数据领域也已经工作了多年&#xff0c;无论所待过的大公司还是小公司&#xff0c;统计出来的数据经常需要查询展示&#xff0c;比如说&#xff1a;用做大屏或者报表或者给一些线上服务提供数据源&#xff0c;经常会要用代码写一套接口服务&#xff0c;需要…

Python中的os模块

整理文件和目录最最最常用的os模块os模块是Python标准库中整理文件和目录最为常用的模块&#xff0c;该模块提供了非常丰富的方法用来处理文件和目录。os.getcwd()作用&#xff1a;获取当前的工作路径&#xff1b;>>> os.getcwd() D:\\ResearchWay\\Code\\PythonCode\…

2023年浏览器哪个好,如何选择浏览器?

浏览器作为电脑必备的软件之一&#xff0c;相信绝大多数人都用过。选择一款好用的浏览器&#xff0c;可以帮助我们提升工作效率。那么&#xff0c;浏览器哪个比较好&#xff0c;我们如何选择合适的浏览器&#xff1f;为了找到集速度、易用性、安全于一身的浏览器&#xff0c;我…

第四十七章 动态规划——状态压缩模型

第四十七章 动态规划——状态压缩模型一、什么是状态压缩二、例题讲解1、AcWing 1064. 小国王&#xff08;1&#xff09;问题&#xff08;2&#xff09;思路&#xff08;3&#xff09;代码2、AcWing 327. 玉米田&#xff08;1&#xff09;问题&#xff08;2&#xff09;思路&am…

晴天科技冲刺上市:实控人丁一波系本科肄业,粤民投为其股东

近日&#xff0c;浙江晴天太阳能科技股份有限公司&#xff08;下称“晴天科技”&#xff09;预披露更新招股书&#xff0c;准备在深圳证券交易所主板上市。据贝多财经了解&#xff0c;晴天科技曾于2022年7月1日递交招股书&#xff0c;此次更新了截至2022年6月30日的财务数据等信…

AcWing 1072. 树的最长路径(DFS)

[TOC](AcWing 1072. 树的最长路径&#xff08;树形DP)) 一、题目&#xff1a; 二、思路&#xff1a; 为了方便&#xff0c;我们利用下面这个图做讲解&#xff1a; 这颗树的最长路径必定经过的是图中的点&#xff0c;因此&#xff0c;**我们可以去枚举经过图中每个点的最长路…

微星武士gf66电脑系统中途安装失败怎么办?

微星武士gf66电脑系统中途安装失败怎么办&#xff1f;有用户购买的微星武士gf66电脑想要进行电脑系统的重新安装&#xff0c;但是在新系统的安装过程中出现了错误&#xff0c;导致系统无法启动了。这个情况可以使用U盘来重装一个系统&#xff0c;恢复电脑的正常使用&#xff0c…

将springboot项目部署到linux上运行的步骤

前言&#xff1a; 博主看了许多的博客&#xff0c;总结出了最有用的部分&#xff0c;将springboot项目完整的运行在了linux虚拟机上。而不是仅仅只在网页打印一句话&#xff0c;就当做运行成功。运行成功页面如下&#xff1a; 运行成果展示&#xff1a; 接下来废话不多说&…

Python 读取大文件

读取大文件 python读取文件一般情况是利用open()函数以及read()函数来完成&#xff1a; f open(filename,r) f.read() 这种方法读取小文件&#xff0c;即读取大小远远小于内存的文件显然没有什么问题。但是如果是将一个10G大小的日志文件读取&#xff0c;即文件大小大于内存…

“深度学习”学习日记。与学习有关的技巧--正则化

2023.1.29 在机器学习的过程中&#xff0c;过拟合是一个常见的问题。过拟合指的是只能够拟合训练数据&#xff0c;但不能很好的拟合测试数据&#xff1b;机器学习的目的就是提高泛化能力&#xff0c;即便是没有包括在训练数据里的测试数据&#xff0c;也希望神经网络模型可以正…

javafx中gif 内存优化

1.背景 桌面程序对内存消耗要求很高&#xff0c;基本的要求是整个程序控制在500M以内。 这就要求每个功能点的内存消耗尽可能地少&#xff0c;大于50M的内存消耗就要想办法优化。 2.现状 gif的显示会导致程序的内存激增。以数字大脑用的雷达图动画为例进行说明&#xff0c;下…

TypeScript 学习笔记总结(一)

ts学习笔记总结。 文章目录一、什么是TypeScript&#xff1f;二、TypeScript 环境搭建三、TS 类型声明四、TS 类型详解五、TS 类型总结六、TS 编译选项1. tsconfig.json的 作用2. tsconfig.json的 配置选项013. tsconfig.json的 配置选项02七、Webpack 打包ts代码一、什么是Typ…

Bayanay:一款基于Python开发的无线网络安全研究工具

关于Bayanay Bayanay是一款基于纯Python开发的无线网络安全研究工具&#xff0c;在该工具的帮助下&#xff0c;无论你身处何地&#xff0c;都可以轻松地对周围地区的无线网络安全状况进行研究与分析。 该工具可以通过使用HTML5的地理位置定位功能并结合Scapy获取到的SSID信息…

LeetCode刷题系列 -- 25. K 个一组翻转链表

给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改变节点内部的值&…

zabbix6,0创建监控项与触发器

zabbix_server IP : 172.31.0.5:10051 zabbix_client IP : 172.31.0.9:10050 zabbix_client已经运行了zabbix-agent,这里我用的是版本2 一、 创建监控项 1、 在客户端创建监控脚本 /etc/zabbix/zabbix_agent2.d #默认配置文件路径 2、 创建配置文件&#xff0c;编写监控脚本…