Linux·权限与工具-make

news2024/9/23 15:25:04

1. Makefile/makefile工具

        首先展示一下,makefile工具如何使用。我们先写一个C语言程序

                

        然后我们建立一个Makefile/makefile文件,m大小写均可。我们在文件中写入这样两行

                

        wq保存退出后,我们使用 make 命令

                 

        可以看到生成了可执行程序,其效果就是我们刚才写的打印出 hello world

        这就是makefile的作用,一个工程中的源文件不计其数,其按类型、功能、模块分放在若干给文件当中,而makefile定义了一系列的规则来指定,哪些文件需要先编译,那些文件需要后编译,和其他一些操作。它是一个“自动化编译”的效果,一旦写好makefile文件,我们就无需自己手动一个一个的敲编译命令,至于要一个make就可以使整个工程完全自动编译起来。

        

1.1 make语法

        下面我们就来拆解一下makefile文件的语法。

                        

        第一行冒号前的部分我们叫目标文件,可以通过make调用目标文件来达到执行下面依赖方法的效果。

        冒号后面的部分我们叫依赖文件列表,这个列表中可以放多个依赖文件,用于提供给下面的依赖方法使用,就是说依赖方法要依赖这个列表中的文件去执行某些操作。

        第二行我们写依赖方法,依赖方法必须以tab开头。

        目标文件和依赖文件列表的集合称为依赖关系,makefile本质是依赖关系和依赖方法的集合。

        事实上,makefile文件的作用是执行事先使用依赖方法写好的一些命令:

                        

                        

        可以看到 make+目标文件 就可以很好的完成我们预设定好的命令,但是它在执行命令的时候都会把命令打印一边,如果不想看见打印命令的话,可以在命令前加上@符号就可以

        这里可以发现我在执行第一行编译的时候并没有加上目标文件,但是在执行第四行和第九行的时候都加上了目标文件。

        这是因为makefile文件,会被make从上到下扫描,第一个目标名,是对于make来说属于可以缺省形成的,也就是说如果make后面什么都不跟,就默认执行第一个目标文件。也就是说,谁放在最开头,谁就可以直接make执行不需要加目标文件名。

1.2 make特性

1.2.1 执行中断

        我们进入代码文件中,故意写出点语法错误,这样编译的话就会导致报错,然后我们再对makefile文件也稍加修改,让它在编译完成之后打印点东西出来

       make执行一下编译命令。

                

        可以看到,在编译报错之后直接跳出了makefile文件,执行被中断 aaa 并没有被打印出来。

1.2.2 更新编译 与 stat命令

        ps:其实这个更新编译的特性属于make指令和gcc编译指令结合后出现的特性,单独使用gcc编译指令是不会出现这一特性的。

        其实我前面写的makefile文件是有问题的,在编译的依赖方法中,实际上是hello文件在依赖hello.c文件,但是我在目标文件中声明的文件却是proc文件作为目标文件在依赖helloc.c文件。如果按我上面这种错误的语法写makefile的话是不会出现更新编译的特性的。

        因此我们先把makefile文件改成正确的语法

                                

       我们clean清理一下,然后make多次,看看现象。

                

        可以看到只成功make了一次,之后再make就表示hello已经是最新了,不再编译。

        这拒绝编译的反应是符合道理的,因为如果一个文件已经是最新了就没必要再重复编译,如果一个文件很大,那重复编译的行为就会浪费掉大量的时间成本。

        其拒绝编译的逻辑就是对比目标文件和依赖文件的更新时间,如果依赖文件的更新时间更早说明目前的目标文件是最新状态,如果依赖文件更新时间更晚,说明hello.c文件已经被更改过了,目标文件也就需要重新编译了。

        这个文件的属性我们可以用 stat 命令来查看。

        其中时间属性就是我圈出来的这三个时间,第一个Access我们称为Atime表示最近文件被访问的时间,它比较没用,更新编译也不看这个时间。它这里面的机制比较奇怪不是说访问一次就一定会记录下来,而是访问到了一定次数才会记录一次,主要是为了防止操作系统要频繁的修改文件的访问时间属性。

        第二个Modify我们称为Mtime表示文件内容最近被修改的时间,第三个Change我们称为Ctime表示文件属性最近被修改的时间。

        修改文件内容可能会牵连到文件属性的修改,比如文件的大小。

        更新编译的逻辑就是根据Mtime进行对比的,如果.c文件修改时间早于目标文件,说明目标文件已经是最新的了,无需编译;如果.c文件修改时间晚于目标文件,说明.c文件被更新过了,目标文件也需编译更新。

1.2.3 .PHONY 设置伪目标

        如果我们想让这个编译指令忽略掉更新限制,我们可以选择将设置伪目标,语法如下

                ​​​​​​​        ​​​​​​​        

        这个语法的意思就是将hello文件变成了一个伪目标,也就是说告诉makefile hello 是一个不存在的文件,此时makefile就不会去特意对比hello和hello.c文件的更新时间,而是直接执行gcc编译指令了。

        这个语法就和我一开始所写的proc目标文件错误有异曲同工之处,它们都是不存在的伪目标,只不过一种是刻意用 .PHONY 指定出来的,一种是真的不存在。

        可以验证一下,将hello设置成伪目标之后是不是可以忽略最新编译限制去make了

        ​​​​​​​        ​​​​​​​        

        也可以将目标文件搞成proc一个真正不存在的目标试试,也是同样的效果。

1.2.4 入栈执行

        我们可以在makefile文件中如下写法,将上节中编译的整个过程写出来

                       

        然后我们保存退出,试试这样make的效果

        ​​​​​​​        ​​​​​​​        

        我们可以通过这里看出,当makefile发现目录的明面上没有hello.o文件,那它就会将依赖方法入栈,然后直到找到出口回归,将栈中所有依赖方法执行。

1.2 make进阶语法

1.2.1 %通配符

        我们在实际使用的时候不会像上面那样把一个文件的编译过程弄的那么复杂,而是会面临一次性想要编译多个文件的需求。

        处理这样的问题可以是使用makefile中类似通配符的东西 % 

        ​​​​​​​        ​​​​​​​        

        由makefile自己推导所需的.c文件,将它们一个一个的交给gcc -c指令,并生成对应的.o文件,其效果我们可以make看一下

        ​​​​​​​        

1.2.2 =变量定义

        makefile中还可以定义和使用变量,用作设定文件名。

        ​​​​​​​        ​​​​​​​        

        定义时等号左右不能有空格,使用变量时用 $(变量) 将变量包起来,这样makefile文件就会将定义好的内容替换到下面的各个位置。

        

1.2.3 $符号的使用

        我们前面说过 $< 的含义是将依赖列表中的文件一个一个的交给指令。

        下面还有   $^   $@   两个指令

        ​​​​​​​        ​​​​​​​        

        其中 $^ 的含义就是将依赖列表中的所有文件一次性交给指令, $@ 的含义是将 : 左侧也就是想要形成的目标文件。

        这种操作就像是在宏替换一样。这样写完后我们就可以通过一份 hello.c 文件生成多个任意名称的文件,只需要修改bin设定的值即可。

1.2.4 一次性形成多个可执行程序

        现在我们想要一次性把 hello.c hello1.c 都形成可执行程序改怎么做

        ​​​​​​​        ​​​​​​​        

        事实上我们可以使用伪目标的依赖列表来巧妙的完成这一需求

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

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

相关文章

无人机模拟训练室技术详解

无人机模拟训练室作为现代无人机技术培训的重要组成部分&#xff0c;集成了高精度模拟技术、先进的数据处理能力及高度交互的操作界面&#xff0c;为无人机操作员提供了一个安全、高效、接近实战的训练环境。以下是对无人机模拟训练室技术的详细解析&#xff0c;涵盖系统基础概…

为TI的 AM355移植uboot和linux内核

一、uboot移植 在移植之前要先对uboot的源码结构有一定熟悉 1.uboot源码顶层目录下各源码文件夹的作用 2.编译后生成的uboot.xxx 各文件后缀含义 关于以上两点社区已经有很多前辈总结的很详细&#xff0c;这里不做赘述。 对于uboot源码分析韦东山老师b站上有免费的课程&#x…

QT中Charts基本用法

QT中Charts基本用法 第一步:创建工程,添加Charts库 第二步:添加charts视图 注意要打上对钩 第三步:添加所需成员 第四步:编写初始化函数 第五步:添加测试数据

C++学习笔记之算法模板

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、双指针1.1 有序数组的合并1.2 快慢指针/删除有序数组中的重复项1.3 求和 二、动态规划2.1 自底向上和自顶向下&#xff08;带备忘录&#xff09;2.2 带有当前状…

浅谈哈希长度扩展攻击

攻击原理&#xff1a; 我们首先需要了解一下Message Authentication codes (MACs) &#xff0c;称为消息验证码&#xff0c;一般用于服务器验证消息的真实性。服务器把密钥和消息连接起来&#xff0c;用摘要算法获取摘要&#xff0c;对于H&#xff08;secret data&#xff09…

RabbitMq的基本理解

MQ概念及同步异步&#xff1a; 同步调用&#xff1a; 是一种编程模型&#xff0c;其中调用者发送请求并等待响应。在同步调用中&#xff0c;调用者会阻塞&#xff0c;直到被调用的方法返回结果。 异步调用: 是一种编程模型&#xff0c;其中调用者发送请求后立即返回&#x…

09结构型设计模式——组合模式

一、组合模式的简介 组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;主要用于处理树形结构中的对象组合问题。它允许你将对象组合成树形结构&#xff0c;以表示部分-整体层次结构。组合模式使得客户端能够统一地对待单个对象和对象组合&a…

SEREN MC2电源匹配器控制器Matching Network Controller手侧

SEREN MC2电源匹配器控制器Matching Network Controller手侧

NC 反转链表

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 给定一个单链…

亲测解决Bundler HTTPError Could not fetch specs from

这个问题源于ruby的网站连接不上&#xff0c;解决方法是修改网页地址或者网络配置。 环境 win11 ruby 问题原文 Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from https://rubygems.org/ due to underlying error <IO::TimeoutEr…

C# 将Dll嵌入exe中发布

一、制作模版Dll 二、在exe工程中添加Dll 1、添加上述“创建Dll”&#xff0c;并修改属性为&#xff1a;不复制到输出目录的嵌入资源 2、引用“Resource”中的dll文件&#xff0c;并修改属性&#xff1a;不复制到本地 三、添加重载Dll代码 1、添加以下代码 class DependentFi…

Modbus 通信协议详解

目录 一、概述二、Modbus 的作用三、Modbus 的工作原理1、四种数据类型2、三种工作模式3、三类功能码3.1 标志功能码3.2 Modbus 封装接口3.3 异常 4、Modbus 协议层4.1 协议数据单元4.2 访问数据4.3 数据模型寻址4.3.1 数据寻址范围4.3.2 数据地址起始值 4.4 大数据类型4.4.1 位…

频率检测计

前言 频率计是一种用于测量信号频率的仪器。它可以准确地确定电子信号的频率&#xff0c;广泛应用于电子设备的测试和维护中。频率计的工作原理通常包括对输入信号进行采样&#xff0c;并通过内部电路计算信号的周期&#xff0c;从而得到频率值。现代频率计通常具有高精度、高稳…

无线通信代码搬运/复现系列(1) : 重新审视具有每天线功率约束的 MIMO 容量:固定点迭代和交替优化

无线通信代码搬运/复现系列(1) “Revisiting the MIMO Capacity with Per-antenna Power Constraint: Fixed-point Iteration and Alternating Optimization,” IEEE Trans. Wireless Commun., vol. 18, no. 1, pp. 388-401, Jan. 2019 by T. M. Pham, R. Farrell, and L.-N. …

C++入门——05STL

STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09;是C标准库的重要组成部分&#xff0c;是一个通用的数据结构和算法库。STL提供了一组经过精心设计的模板类和函数&#xff0c;用于处理各种常见的数据结构&#xff08;如容器&#xff09;和算法&…

六. 部署分类器-preprocess-speed-compare

目录 前言0. 简述1. 案例运行2. 代码分析2.1 main.cpp2.2 preprocess.cpp 3. 补充说明结语下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习课程第六章—部署分类器&…

嵌入式面经篇八——进程线程

文章目录 前言一、进程&线程1、异步 IO 和同步 IO 区别&#xff1f;2、进程间通信方式&#xff1f;3、进程的地址空间模型&#xff1f;4、进程的五种状态分别是?5、子进程从父进程继承的资源有哪些&#xff1f;6、什么是进程上下文、中断上下文&#xff1f;7、如何防止僵尸…

写了一个分页 sql,因为粗心出了 bug 造成了 OOM!

大家好&#xff0c;我是君哥。 最近上完线后&#xff0c;凌晨收到一个生产告警&#xff0c;一个 OOM 异常导致了服务重启。今天来分享一下这个事故。 1.事故现场 事故的代码逻辑并不复杂&#xff0c;从一个大概有 8 万数据的表里面查出数据&#xff0c;汇总后对数据做处理。…

高校宣讲会管理系统--论文pf

TOC springboot370高校宣讲会管理系统--论文pf 第1章 绪论 1.1选题动因 当前的网络技术&#xff0c;软件技术等都具备成熟的理论基础&#xff0c;市场上也出现各种技术开发的软件&#xff0c;这些软件都被用于各个领域&#xff0c;包括生活和工作的领域。随着电脑和笔记本的…

【myz_tools】Python库 myz_tools:Python算法及文档自动化生成工具 - 0.2.0版更新

文章目录 0.2.0 更新内容如下函数generate_2d_combinations_iter函数generate_row_permutations函数calculate_total_permutations函数display_combinations函数evaluate_list_similarity函数check_unique 写在前面关于库库使用库内所有函数目录文件名称: common_maths.py函数部…