Linux相关概念和重要知识点(6)(make、makefile、gdb)

1.make、makefile

(1)什么是make、makefile?

在我们写完代码后,要编译运行,如果有多个.c文件就需要每次都自己用gcc -o来处理,这十分麻烦。当我们想要自定义多个文件的处理时,我们会浪费很多时间在重复的事情上,我们需要一种自动化的、可自定义文件处理方式的程序,make和makefile就是为此而生的。大型项目一定离不开make和makefile。

make和makefile联系紧密,make是一个命令,makefile是一个文件,这个文件以某种格式来自定义可执行程序的方式,当使用make时就调用这个makefile文件来处理。

(2)makefile结构

makefile本质是依赖关系和依赖方法的集合。举个例子,完成老师向学生下达任务这件事需要两个条件:首先就是这两个人得是师生关系,即依赖关系;其次就是下达任务这个动作,这叫依赖方法。要办成一件事,依赖方法和依赖关系缺一不可,首先建立依赖关系,其次传递依赖方法。

格式:(目标文件):(依赖文件)   -> 依赖关系

(tab) (依赖方法)

类似于函数的传参和返回值,依赖文件类似传递的参数,而目标文件则是返回值,或者说是计划生成的文件。隔行后就可以开始写我们的依赖方法了,类似函数体。但是要注意每行依赖方法指令必须要顶格使用tab,就像python的函数一样,对缩进的要求很高。

下面是一个简单的示例。

当我们执行make时,就会根据makefile在当前目录下找test.c文件,类似函数的参数,目标生成的文件就是test。在依赖方法中我们显式写了目标文件和依赖文件,名字也符合规范。按照我们的指令一行行执行,最终生成指定文件。

我们发现,我们不仅将指令的结果打印出来了,还将指令的内容打印出来了。当我们在依赖方法每行前面加上@时,就能只打印结果而没有指令本身,这叫关闭回显。

(3)依赖关系

我们需要进一步理解依赖文件和目标文件的作用,根据上面的例子,有人肯定会觉得目标文件和依赖文件就等同于函数的参数和返回值,但事实并不是,它们和函数有很大区别

看一下下面的依赖关系和结果

我们发现,目标文件是a,没有依赖文件,但是实际执行指令时用到了test.c,生成的文件又是test,和目标文件a完全不沾边,这应当如何解释?

目标文件理解成一种建议生成的文件或是一种规范,规范更好,不规范也不会强制终止。因为在有的时候不需要生成文件,而目标文件一定要写,所以这是一种妥协。但是我们必须保证依赖文件必须能够找到,因为不需要依赖文件时我们可以不写,不会存在目标文件的那种情况。当执行依赖方法时,每一行指令其实都被展开到当前工作目录下执行,上面的gcc -o test test.c是一句完整的指令,它不需要依赖任何的依赖文件,也能合理地生成自己的文件,和目标文件也没有任何关系。

那么依赖文件和目标文件存在有何意义?

①声明依赖关系,实现不同功能的区分

在makefile我们可以写很多指令,实现不同功能,不同功能的指令都需要先声明依赖关系,再执行依赖方法。依赖文件和目标文件存在就是为了声明依赖关系。在目标文件和依赖文件没有实际意义时它更像一种标识,标志这个功能将要开始实现,也可以和其它功能的指令作出区分。

当我们使用make时默认执行第一个依赖关系下的依赖方法。要执行其它的需要make (目标文件)

在makefile里,目标文件名不能重复,否则会导致歧义。

②自动推导

在很多情况下依赖文件和目标文件是一种建议,是一种规范,规范必定带来好处,其中有一个就是自动推导。

当我们想要通过.c先生成一个.o,再生成一个可执行文件,那就可以利用自动推导来处理。

当make之后会自动执行第一个依赖关系,按照我们写的依赖文件在目录中查找,如果找不到,会将这个依赖关系先放入栈,再找目标文件是刚刚依赖文件的依赖关系,找到了如果发现依赖文件还是找不到,那就继续入栈,以此类推。如果一个依赖关系的目标文件和依赖文件都能在当前目录找到,那就依次出栈,执行指令。

注意推导到最后的依赖关系时依赖文件一定找得到,否则就报错,和前面的规则一样。

根据上面的规则,看一下下面的makefile,在make和make clean时结果是什么

结果

当make时,会根据目标文件和依赖文件入栈出栈,当我们递归生成文件时,就需要好好规范一下目标文件和依赖文件的写法,保证能够推导到其它依赖关系上。

③通配符

当我们不写依赖文件时,依赖方法里依然可以用到目录里面的文件,因为依赖方法的指令会被展开执行,既然显式写出了调用的文件(即构成了一句完整的指令),就能正常执行。

当我们有多个.c时,我们需要逐个对所有.c进行编译,当要处理的文件都有一个相同特征时,通配符就派上用场了,在makefile里,百分号%就是通配符的意思,和指令里的*一样

注意通配符对应的依赖关系很特殊,要么整个依赖关系都用通配符,要么都不用。并且make时是无法定位由通配符组成的通配符的依赖关系的,就算名义上它是第一个依赖关系。需要我们写一个自动推导的依赖关系。

④变量和自动变量

如果我们想要依赖关系列出来的文件和实际依赖方法使用的文件有较强相关性,可以使用自动变量。

$@代表目标文件,$^代表全部依赖文件,$<代表逐个依赖文件

定义的变量可以以$(变量)形式使用,变量和自动变量的使用可以帮助我们更统一的管理文件调用,生成的文件,极大降低了重复的工作

(4).PHONY伪目标

常规的依赖关系都会根据依赖文件和目标文件的Modify来决定是否需要执行。如果依赖关系里面的文件都有且目标文件的Modify时间更晚,那就不会执行。

.PHONY:(伪目标)声明伪目标,会自动忽视伪目标的时间比对。后续直接使用(伪目标):(依赖文件)来定义依赖关系即可。我们也可以用touch显式修改时间来绕过检查。

一个.PHONY声明一个伪目标

伪目标的作用就是为了执行一些指令,不要求生成文件生成

2.gdb

gdb是调试代码的工具,我们利用gdb调试的本质是帮助我们快速找出问题,然后自己解决。这里分享一些指令和注意事项

cgdb:我们可用cgdb来替代gdb,操作一致但代码有展示,更方便。

检查是否安装:gdb --version

调试前提:编译选项加上-g(debug,添加调试信息)。默认情况都是release,无调试信息

重复操作:gdb中直接回车默认执行上一条指令

显示代码:l (num)将第num行居中显示,l (函数名)居中显示当前函数名所在行,l (源文件):(函数名/行号)查看指定文件中的代码,注意每次回车都会执行l(翻页,每次10行)

打断点:b (行数/函数名)给指定位置打断点,info b可以查看自己打的断点,每个断点都有一个编号Num

打条件断点:b (行数) if (变量) == (值)打一个条件断点,只在if成立时截停。condition (断点编号) (条件) 可以给已有的断点添加条件

暂时禁用断点:enable (断点编号)打开断点,disable (断点编号)关闭断点

删除断点:d (断点编号)删除断点,要通过info b查看自己打的断点的编号Num。注意每个断点编号对应一次断点操作,不会复用已删除的断点编号

执行代码:r在没有断点时直接将代码运行完,有断点时执行至第一个断点。调试过程中再按r意味着重新启动调试

逐语句和逐过程:n逐过程(不会进入函数),s逐语句(会进入函数)

执行至下一次断点:c直接执行到当前断点的下一个断点

执行至指定行数:until (行数)跳过中间的代码,直接执行到指定行

按函数运行:finish能把当前函数跑完,如果期间有断点会被截停,main函数不行(最外围函数不支持)。断点 + finish + until + c这几个指令组合起来很有用,能帮助我们查找bug发生点,进而实现对大的代码块进行区间debug

调试中修改:set bar (变量)=(新值),直接修改代码中的变量的值,帮助我们在调试时能根据猜想及时检验问题,如果错了也可以继续修改,而不必退出gdb检验

监视:display (变量)每次执行都会监视变量,display (监视编号)关闭显示,p (表达式)临时显示当前变量或表达式的值。监视编号也是不可复用的,每次打印监视变量就会打印其监视编号

检测变量:watch (变量)检测变量的值是否变化,它是watchpoint,能用info b查看,也能d删除。如果变量数值变了,就会显示出来,而不像display那样每次都显示

查看当前函数栈帧:bt显示逐语句位置,显示每层函数调用位置

自动变量:info locals显示当前栈帧定义的变量信息

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全国职业院校技能大赛(大数据赛项)-平台搭建Spark、Scala笔记

Spark作为一个开源的分布式计算框架拥有高效的数据处理能力、丰富的生态系统、多语言支持以及广泛的行业应用。Scala是一种静态类型的编程语言&#xff0c;它结合了面向对象编程和函数式编程的特性&#xff0c;被誉为通用的“大数据语言”。而二者的结合更能迸发出新奇的化学反…

ER论文阅读-Decoupled Multimodal Distilling for Emotion Recognition

基本介绍&#xff1a;CVPR, 2023, CCF-A 原文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2023/papers/Li_Decoupled_Multimodal_Distilling_for_Emotion_Recognition_CVPR_2023_paper.pdf Abstract 多模态情感识别&#xff08;MER&#xff09;旨在通过语言、…

MODELS 2024:闪现奥地利,现场直击报道

周末出逃&#xff01;小编闪现至奥地利林茨&#xff0c;亲临第27届MODELS 2024国际会议&#xff0c;以第一视角引领你深入会议现场&#xff0c;领略其独特风采。利用午饭时间&#xff0c;小编紧急码字&#xff0c;只为第一时间将热点资讯呈现给你~ 会议介绍&#xff1a; MODEL…

数据结构篇--折半查找【详解】

折半查找也叫做二分查找或者对数查找&#xff0c;是一种在有序数组中查找特定元素的查找算法。 折半查找的算法步骤如下&#xff1a; 将目标关键字key与数组中的中间元素比较&#xff0c;若相等则查找成功。key大于中间元素&#xff0c;就到数组中大于中间元素的部分进行查找&…

吴恩达深度学习笔记:卷积神经网络(Foundations of Convolutional Neural Networks)2.1-2.2

目录 第四门课 卷积神经网络&#xff08;Convolutional Neural Networks&#xff09;第二周 深度卷积网络&#xff1a;实例探究&#xff08;Deep convolutional models: case studies&#xff09;2.1 为什么要进行实例探究&#xff1f;&#xff08;Why look at case studies?&…

【ComfyUI】自定义节点ComfyUI_LayerStyle——模仿 Adob​​e Photoshop 的图层样式、图层混合、图文混合、添加不可见水印

官方代码&#xff1a;https://github.com/chflame163/ComfyUI_LayerStyle.git 相关资料下载&#xff1a;https://pan.baidu.com/s/16vmPe6-bycHKIjSapOAnZA?pwd0919 简介 在ComfyUI画布点击右键 - Add Node, 找到 “&#x1f63a;dzNodes”。 节点根据功能分为5组&#xff…

深入Android UI开发:从自定义View到高级布局技巧的全面学习资料

在Android开发的世界中&#xff0c;UI设计和实现是吸引用户的关键。本文将为您介绍一套全面的Android UI开发学习资料&#xff0c;包括详细的学习大纲、PDF文档、源代码以及配套视频教程&#xff0c;旨在帮助您从自定义View到高级布局技巧&#xff0c;全面提升您的UI开发技能。…

基于SpringBoot+Vue+MySQL的电影院购票管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着电影产业的蓬勃发展&#xff0c;电影院已成为人们休闲娱乐的重要场所。然而&#xff0c;传统的电影院购票管理系统存在诸多不便&#xff0c;如购票流程繁琐、排队时间长、无法提前选座等问题&#xff0c;给观众的观影体验带…

uni-data-select 使用 localdata 传入数据出现 不回显 | 下拉显示错误的 解决方法

目录 1. 问题所示2. 正确Demo3. 下拉显示错误(Bug复现)4. 下拉不回显(Bug复现)1. 问题所示 uni-app的下拉框uni-data-select 使用 localdata 传入数据 主要总结正确的Demo以及复现一些Bug 数据不回显数据不显示下拉选项2. 正确Demo 详细的基本知识推荐阅读:uni-app中的…

java项目之健身房管理系统源码(springboot)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的健身房管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 健身房管理系统的主要使用…

ModbusTCP通讯错误的排查

Modbus是一种由MODICON公司开发的工业现场总线协议标准&#xff0c;是一项应用层报文传输协议。该协议用于传输数字和模拟变量[1]。有关该协议的报文具体格式&#xff0c;以及一些基本概念&#xff0c;见[1]。 本文以一个例子&#xff0c;阐述当ModbusTCP通讯出现错误的时候&a…

深度学习01-概述

深度学习是机器学习的一个子集。机器学习是实现人工智能的一种途径&#xff0c;而深度学习则是通过多层神经网络模拟人类大脑的方式进行学习和知识提取。 深度学习的关键特点&#xff1a; 1. 自动提取特征&#xff1a;与传统的机器学习方法不同&#xff0c;深度学习不需要手动…

VOC2007数据集

目标检测入门code 文件目录 下载数据集——在官网下载VOC2007数据集 下载训练数据集 TRAIN data 下载测试数据集 TEST data 解压数据集 解压——训练数据集&#xff0c;在服务器上&#xff0c;目录为VOCdevkit 部分文件目录 全部文件总目录 解压——测试数据集 &#xff08;…

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.AVL树

1.AVL 树 1.1AVL 树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查 找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数学家G.M.Adelson-Velskii 和E.M.Landis在1962…

数据结构之图的遍历

文章目录 广度优先遍历深度优先遍历 广度优先遍历 广度优先遍历过程类似于二叉树的层序遍历&#xff0c;从起始顶点开始一层一层向外进行遍历 比如现在要找东西&#xff0c;假设有三个抽屉&#xff0c;东西在那个抽屉不清楚&#xff0c;现在要将其找到&#xff0c;广度优先遍历…

【FFT】信号处理——快速傅里叶变换【通俗易懂】

快速傅里叶变换&#xff08;Fast Fourier Transform, FFT&#xff09;是一种用于将信号从时间域转换到频率域的算法。 傅里叶变换的核心思想是&#xff1a;任何周期性信号都可以分解成多个不同频率的正弦波或余弦波的叠加。 简单来说&#xff0c;FFT可以帮助我们理解一个信号…

鲲鹏计算这五年:硬生态基本盘稳住,才能放手进击软生态

文 | 智能相对论 作者 | 叶远风 数智化深入发展、新质生产力成为主旋律的当下&#xff0c;本土计算产业的发展被寄予越来越多的关注和期待。自2019年开启以来&#xff0c;鲲鹏计算产业生态已经整整走过5个年头。 因此&#xff0c;今年华为全联接大会的鲲鹏之夜&#xff0c;在…

大模型价格战,打到了负毛利,卷or不卷?

国产大模型淘汰赛在加速。这轮淘汰赛会持续一两年&#xff0c;只有少数真正具备实力的基础模型企业能继续活下去 中国市场的大模型价格战已经打了近半年。这轮价格战已经打到了负毛利&#xff0c;而且暂时没有停止迹象。头部云厂商仍在酝酿新一轮降价。这轮降价会在今年9月下旬…

【初阶数据结构】详解二叉树 - 树和二叉树(三)(递归的魅力时刻)

文章目录 前言1. 二叉树链式结构的意义2. 手搓一棵二叉树3. 二叉树的遍历&#xff08;重要&#xff09;3.1 遍历的规则3.2 先序遍历3.3 中序遍历3.4 后序遍历3.5 遍历的代码实现3.5.1 先序遍历代码实现3.5.2 中序遍历代码实现3.5.3 后序遍历代码实现 4. 统计二叉树结点的个数5.…

【iOS】MVC架构模式

文章目录 前言MVC架构模式基本概念通信方式简单应用 总结 前言 “MVC”&#xff0c;即Model&#xff08;模型&#xff09;&#xff0c;View&#xff08;视图&#xff09;&#xff0c;Controller&#xff08;控制器&#xff09;,MVC模式是架构模式的一种。 关于“架构模式”&a…