Linux开发工具——make/Makefile

目录

一、什么是makefile?

二、为什么要有makefile?

三、makefile的使用

1.依赖关系与依赖方法

2.伪目标

3.定义变量

4.特殊符号

四、makefile的执行逻辑


一、什么是makefile?

        Makefile是一种自动化构建工具,make是一条指令,Makefile是一个文件,当我们创建名为Makefile的文件后在Makefile中按照一定的规则制定一些命令。然后我们在命令行输入make命令后会自动执行Makefile文件中的指令。

二、为什么要有makefile?

  • 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Visual C++的nmake,Linux下GNU的make。
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

三、makefile的使用

首先在我们的项目下创建一个名为Makefile或名为makefile的文件,然后使用vim打开进行编辑。

1.依赖关系与依赖方法

        假如我们有一个code.c文件,现在需要编译生成名为code的可执行文件,我们可以在Makefile中这样写:

code:code.c
    gcc code.c -o code

依赖关系:就是所要生成的这个目标文件所依赖的文件是哪些。

依赖关系:就是所要生成的这个目标文件所依赖的方法是哪些。

注意:在依赖方法的前面需要加一个Tab制表符,使用4个空格不合法。

在Makefile写完以上指令后我们回到命令行,输入make命令则会有以下效果:

 我们使用make指令后它会自动显示出gcc code.c -o code,如果不想让它显示可以在依赖方法前面加@如:

code:code.c
    @gcc code.c -o code

2.伪目标

        伪目标文件也就是说它并不会在自己的目录下真生成一个目标文件,它更像是一条指令,用了就没了但是可以多次使用,只要给目标文件用.PHONY修饰那么它就成为伪目标了,如下:

.PHONY:clean
clean:
    rm -f code

因为生成clean这个目标不需要依赖任何文件所以就不用写。

在命令行执行.PHONY修饰的文件我们需要使用make+伪目标名,比如这里我们可以在命令行输入

make clean

3.定义变量

        在某些时候我们为了方便后期修改通常会用变量来代替各种文件或指令,而在使用时需要用$符号加()可以理解为把它解包装,如把以上的命令全部改为变量的形式:

BIN=code
SRC=code.c
CC=gcc
FLAGS=-o
$(BIN):$(SRC)
    $(CC) $(SRC) $(FLAGS) $(BIN)

4.特殊符号

%.o表示所有以.o为结尾的文件,同理%.c表示所有以.c结尾的文件。

$@:所有目标文件

$^:所有依赖的文件

$(shell ls *.c)或$(wildcard *.c): 在该目录里的所有以.c结尾的文件

$(SRC: .c = .o):SRC变量名表示的文件的.c变成.o生成新的文件名。

那么我们可以做出以下操作:

BIN=code 
CC=gcc
#SRC=$(shell ls *.c)
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)
LFLAGS=-o
FLAGS=-c
RM=rm -f 
$(BIN):$(OBJ)
     @$(CC) $(LFLAGS) $@ $^
     @echo "linking ... $^ to $@"
 %.o:%.c
     @$(CC) $(FLAGS) $<
     @echo "compling ... $< to $@"
 .PHONY:clean
 clean:
     $(RM) $(OBJ) $(BIN)  

注:

  • 其中#表示屏蔽,这跟我们一般写代码用的屏蔽方式不一样
  • 使用echo打出信息可以方便我们知道程序是否在正常执行。
  • 不把源文件直接生成可执行文件而是先生成.o文件是因为后期对部分文件进行修改后可以单独编译再与原来编译好的文件一起做库链接,而不是全部文件重新编译一遍。 而如果直接把源文件生成可执行文件的话,到时候一个文件修改就需要全部文件重新编译一遍,效率非常的低。

四、makefile的执行逻辑

比如我们写这样一段指令:

        上面的指令是能正常运行的,但我们发现在执行第一个语块的时候并没有code.o这个依赖文件,code.o需要在下一个语块中才能生成。其实makefile的执行逻辑是这样的,它在执行到一个文件不完整的语块的时候,会类似的先把它放在一个栈结构中然后往后去执行,直到后面的指令执行完需要它出栈的时候才执行,此时如果该语块依旧文件不完整则会报错。

        一个目标文件被.PHONY修饰后变成伪目标是可以总是被执行的。而一个普通的目标文件只能被执行一次。这也是一种提高编译效率的方式,因为同样的内容已经生成了一份就没必要多次生成。

        而当涉及的依赖文件的内容被修改时make指令才能再次被执行。但是Makefile如何知道某个文件被修改过呢?其实是通过文件的时间属性来判断的,我们可以通过stat+文件名来查看,如:

  • Access时间:文件的最近访问时间。当文件内容被读取时,这个时间戳会更新。
  • Modify时间:文件内容的最近修改时间。当文件的内容发生变化时,这个时间戳会更新。
  • Change时间:文件属性的最近修改时间。这里的文件属性包括文件的权限、所有者、所属组等元数据。

        可以巧记为“ACM”时间。makefile通过比较目标文件与依赖文件的Modify时间,如果依赖文件的Modify时间比目标文件的Modify时间要新,则可以通过make指令再次生成目标文件。

非常感谢您能耐心读完这篇文章。倘若您从中有所收获,还望多多支持呀!74c0781738354c71be3d62e05688fecc.png

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

`掌握Python-PPTX,让PPt制作变得轻而易举!`

文章目录 掌握Python-PPTX&#xff0c;让PPT制作变得轻而易举&#xff01;背景介绍python-pptx 是什么&#xff1f;如何安装 python-pptx&#xff1f;简单库函数使用方法应用场景常见Bug及解决方案总结 掌握Python-PPTX&#xff0c;让PPT制作变得轻而易举&#xff01; 背景介绍…

uniapp vue3 使用echarts-gl 绘画3d图表

我自己翻遍了网上&#xff0c;以及插件市场&#xff0c;其实并没有uniapp 上使用echarts-gl的样例&#xff0c;大多数都是使用插件市场的echarts的插件 开始自己尝试直接用echartsgl 没有成功&#xff0c;后来尝试使用threejs 但是也遇到一些问题&#xff0c;最后我看官网的时…

windows运行ffmpeg的脚本报错:av_ts2str、av_ts2timestr、av_err2str => E0029 C4576

问题描述 我目前的环境是&#xff1a; 编辑器&#xff1a; Microsoft Visual Studio Community 2022 (64 位) 运行的脚本是ffmpeg自带的remux样例&#xff0c;只不过我想用c语言执行这个样例。在执行的过程中报错如下图&#xff1a; C4576 后跟初始值设定项列表的带圆括…

Moore Perf System 1.1版本

Moore Perf System&#xff08;一款性能分析工具&#xff09; 提供可视化界面&#xff0c;在时间轴上按时间顺序显示 CPU 和 GPU 的事件、吞吐和性能指标&#xff0c;帮助开发人员方便、快速、准确的定位到系统级别的性能瓶颈&#xff0c;进而进行针对性分析和优化&#xff0c;…

『VUE』19. scope避免组件之间样式互相覆盖(详细图文注释)

目录 使用多个组件带有样式分析如何避免css覆盖总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 使用多个组件带有样式 ComPonent1.vue <template><h3>ComPonent1.vue</h3> </template><script&g…

数据结构 C/C++(实验二:栈)

&#xff08;大家好&#xff0c;今天分享的是数据结构的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 提要&#xff1a;实验题目 一、实验目的 二、实验内容及要求 三、算法思想 实验1 实验2 四、源程序及注释…

软考背诵笔记

计算机硬件组成 运算器&#xff0c;控制器&#xff0c;存储器&#xff0c;输入设备&#xff0c;输出设备 中央处理单元&#xff08;CPU&#xff09; 控制器组成 指令寄存器&#xff08;IR&#xff09;:暂存cpu执行指令 程序计数器&#xff08;PC&#xff09;:存放下一条执…

面试问答-1

目录 1、线程和进程的概念&#xff0c;区别、以及什么时候用线程什么时候用进程 1.1 概念 1.2 区别 1.3 选择 2、TCP/IP分几层&#xff0c;每层的核心任务是什么 1.tcp/ip模型 tcp&#xff1a; udp&#xff1a; tcp、udp的区别 tcp/udp的连接过程&#xff1a; 3、htt…

矩阵特殊打印方式

小伙伴们大家好&#xff0c;好几天没更新了&#xff0c;主要有个比赛。从今天起继续给大家更新&#xff0c;今天给大家带来一种新的题型&#xff1a;矩阵特殊打印方式。 螺旋打印矩阵 解题思路 首先给大家看一下什么是螺旋方式打印&#xff1a; 就像这样一直转圈圈。 我想大多…

Docker篇(Docker安装)

目录 一、Centos7.x 1. yum 包更新到最新 2. 安装需要的软件包 3. 设置 yum 源为阿里云 4. 安装docker 5. 安装后查看docker版本 6. 设置ustc镜像源 二、CentOS安装Docker 前言 1. 卸载&#xff08;可选&#xff09; 2. 安装docker 3. 启动docker 4. 配置镜像加速 …

计算机网络——路由器构成

算路由表是分布式去算——你算你的&#xff0c;我算我的 输出队列非先来先传 调度发生在哪里 缓存队列一般是应对——来数据方向的速度过快问题

C# 实现读取Excel文件并设置单元格计算公式再保存

背景&#xff1a;需求需要读取数据导出成Excel文件&#xff0c;并且其中有一列需要赋值为公式&#xff0c;用于用户自己修改数据自动计算 导出Excel&#xff0c;我用到开源包MiniExcel Gitee地址MiniExcel源码介绍&#xff0c;功能说明 Nuget安装 搜索MiniExcel 导出代码如下&a…

基于matlab的SVPWM逆变器死区补偿算法仿真研究

背景介绍&#xff1a; 三相脉宽调制(pulse width modulation&#xff0c;PWM)电压源逆变器(voltage source inverter&#xff0c;VSI)的死区效应可导致电机相电压和相电流畸变、零电流钳位效应以及转矩和转速脉动&#xff0c;系统性能降低。为提高系统运行性能&#xff0c;对V…

Spring Validation数据校检

文章目录 Spring Validation1 关于Spring Validation2 使用流程3 快速入门4 运行异常处理4.1 说明4.2 处理异常4.3 明确提示消息 5 常用注解5.1 NotNull注解5.2 NotEmpty 注解5.3 NotBlank 注解5.4 Size 注解5.5 Range 注解 6 非POJO参数校验6.1 使用流程6.2 使用示例 Spring V…

2024数据库国测揭晓:安全与可靠的新标准,你了解多少?

2024年数据库国测的结果&#xff0c;于9月份的最后一天发布了。 对于数据库行业的从业者来说&#xff0c;国测是我们绕不过去的坎儿。那么什么是国测&#xff1f;为什么要通过国测&#xff0c;以及国测的要求有哪些&#xff1f; 这篇文章带大家一探究竟。 国测 自愿平等、客…

前端入门一之CSS知识详解

前言 CSS是前端三件套之一&#xff0c;在MarkDown中也完美兼容这些语法&#xff1b;这篇文章是本人大一学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。 文章目录 Emmet语法&#xff1a;CSS基本语法&#xff1a;css语法结构只有3种&#xff1a…

虚拟现实和增强现实技术,如何打造沉浸式体验?

内容概要 在这个科技飞速发展的时代&#xff0c;虚拟现实&#xff08;VR&#xff09;与增强现实&#xff08;AR&#xff09;技术的结合就像调皮的小精灵&#xff0c;一下子把我们的生活变得神奇又有趣。想象一下&#xff0c;你正在游戏中与精灵搏斗&#xff0c;突然间身边的客…

EL面包屑导航实现

前言 el-breadcrumb 是 Element Plus 中的面包屑导航组件&#xff0c;主要用于展示当前页面在整个应用程序中的位置&#xff0c;并提供导航功能 https://element-plus.org/zh-CN/component/breadcrumb 基础用法 在 el-breadcrumb 中使用 el-breadcrumb-item 标签表示从首页开…

Qt 练习做一个登录界面

练习做一个登录界面 效果 UI图 UI代码 <?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>Dialog</class><widget class"QDialog" name"Dialog"><property name"ge…

c语言简单编程练习10

1、typedef和#define的区别 在用作数据类型替换时的区别&#xff1a; #include <stdio.h> #include <unistd.h>typedef char * A; //typedef需要&#xff1b; #define B char *int main(int argc, char *argv[]) {A a,b;B c,d;printf("a_size%ld\n"…