【Linux】Linux项目自动化构建工具 - make/Makefile

news2024/11/10 7:49:07

在这里插入图片描述

目录

  • 一、make/Makefile的背景
  • 二、make/Makefile的基本概念
  • 三、依赖关系
  • 四、依赖方法
  • 五、make/Makefile原理
  • 六、Makefile的伪目标
  • 七、Makefile的变量
  • 八、Makefile的推导能力
  • 结尾

一、make/Makefile的背景

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

二、make/Makefile的基本概念

Makefile的基本结构

目标文件: 依赖文件
<tab>命令(command)  
<tab>命令...

实例

mytest:test.c
	gcc test.c -o mytest                                                                                                                
.PHONY:clean
clean:
    rm -f mytest

注意Makefile文件中的第一行尽量不要是空行,虽然make工具本身能够处理以空行开头的Makefile,但在某些复杂的构建场景中,空行可能会与Makefile中的其他元素(如变量定义、条件语句等)产生意外的交互。
在这里插入图片描述

make的执行目标

  • 如果你想要make执行特定的命令或目标,可以在make命令后明确指定该目标名称。
    在这里插入图片描述

  • 如果没有指定目标,make将默认执行Makefile中的第一个目标(这通常是Makefile中定义的第一个规则所对应的目标)。
    在这里插入图片描述


三、依赖关系

依赖关系指的是构建过程中,一个目标文件依赖其他文件(源文件、头文件、其他目标文件),依赖关系在Makefile中通过特定的语法来定义,通常使用冒号(:)来分隔目标文件和它的依赖文件。

mytest:test.c
	gcc test.c -o mytest                                                                                                                
.PHONY:clean
clean:
    rm -f mytest

以上面的Makefile文件举例子,mytest是目标文件依赖于test.c文件


四、依赖方法

依赖方法实际上是指Makefile中定义的用于构建目标文件的命令序列。这些命令告诉make如何根据依赖关系来生成目标文件。在Makefile中,每个目标文件后面跟着的一个Tab键开头就是该目标文件的依赖方法。

mytest:test.c
	gcc test.c -o mytest                                                                                                                
.PHONY:clean
clean:
    rm -f mytest

以上面的Makefile文件举例子,gcc test.c -o mytest.crm -f mytest就是依赖方法


五、make/Makefile原理

这里先对下面图片出现的现象提一个问题,为什么make只能执行一次,而修改源文件后就可以再一次make,为什么make/Makefile总是不让我们重新编译代码呢?系统是怎么做到的?
在这里插入图片描述

还记得在常见指令那篇文章中的touch指令里延伸讲到了一个stat指令,stat指令能够查看一个文件的详细信息,包括文件最近访问时间(Access Time)、文件内容最近修改时间(Modify Time)和文件属性最近修改的时间(Change Time)。

以下面的图片为例来讲解下面的问题,首先我们在没有生成可执行程序的情况下执行一次make是可行的,当进行第二次make的时候却不能执行了,这时候我们来使用stat指令查看一下两个文件的文件内容最近修改时间,我们能发现可执行程序的最近修改时间大于源文件,真的是因为这个吗?接下来我们对源文件进行修改,导致源文件的最近修改时间变大,超过了可执行程序,源文件的最近修改时间大于可执行程序就能够再一次执行make了吗?是的!源文件的最近修改时间大于可执行程序就能够再一次执行make了

在这里插入图片描述

问题为什么make/Makefile总是不让我们重新编译代码呢?
解答make/Makefile总是不让我们重新编译我们的代码的原因是提高编译效率。当你有一个大型项目,包含许多源文件、库依赖和复杂的构建逻辑时,手动编译整个项目会非常耗时且容易出错。Makefile 通过定义构建规则来自动化这个过程,并且它非常擅长识别哪些部分需要被重新编译,哪些部分已经是最新的,因此不需要重新编译。


问题系统是怎么做到的?
解答通过对比源文件和可执行程序的文件内容最近修改时间来体现源文件的新旧。具体来说就是:

第1次的时候,一定是先有源文件,才能有可执行程序
源文件修改时间 < 可执行程序修改时间

第2/n次的时候,我们对源文件进行修改
源文件修改时间 > 可执行程序修改时间

源文件修改时间 > 可执行程序修改时间时,可以使用make重新对源文件进行编译生成可执行程序,那么源文件与可执行程序之间的关系又会变为源文件修改时间 < 可执行程序修改时间


问题如何做到不修改源文件的前提下就能使用make重新对源文件进行编译?

解答:若是想不对源文件进行修改就能使用make重新对源文件进行编译,那么可以对文件使用touch指令,在常见指令这篇文章中讲到了,当文件不存在时touch指令创建文件,当文件存在时则是更新文件时间。

在这里插入图片描述


六、Makefile的伪目标

伪目标是一个不实际生成文件的目标,它用于执行一些特定的命令。伪目标在Makefile中通常以.PHONY声明,以防止与文件名冲突。

上面我们提到了make/Makefile总是不让我们重新编译代码,那么有没有一种方法能够让make/Makefile总是让我们重新编译代码呢?

那么这里就要提到Makefile的伪目标了,被.PHONY标记的目标成为伪目标,能让make/Makefile每次都重新编译代码。

在这里插入图片描述
一般.PHONY我们用来标记这种clean、install等(清理操作、安装操作等)的目标文件,我们将它设置为伪目标,意味着这些伪目标总是被执行的。


七、Makefile的变量

Makefile也支持变量的定义和使用,类似于C语言中的宏。变量的定义和使用可以帮助减少重复代码,提高Makefile的可维护性。

  • 变量赋值:Makefile中可以使用=、:=、?=、+=等符号进行变量赋值。
    • =:最普通的赋值方式,变量的值在整个Makefile中最终被指定。
    • :=:直接赋值,赋予当前位置的值。
    • ?=:如果该变量没有被赋值,则赋予等号后面的值。
    • +=:将符号后面的值添加到前面的变量上。
  • 变量使用:在Makefile中,可以通过$(变量名)的方式来引用变量的值。

将源文件test.c赋值给src,若源文件不止一个,那么可以在源文件的后面添加空格,然后就可以继续添加源文件了。
在这里插入图片描述


八、Makefile的推导能力

隐含规则(这里只是举例子并不深入理解)

以下图为例,首先,Makefile 会检查目标 mytest 是否已经是最新的,这里由于 mytest 不存在,Makefile 会继续处理。接下来,Makefile 会查看 mytest 的依赖项 test.o,这里由于 test.o 也不存在,Makefile 需要构建一个构建计划来生成 test.o。由于 Makefile 中没有为 test.o 编写显式的构建规则,Makefile 会搜索是否有适用于 .o 文件从 .c 文件构建的隐含规则。找到了适用的隐含规则(通常是将 .c 文件编译成 .o 文件的规则),Makefile 会自动调用 C 编译器来编译 test.c 并生成 test.o。
在这里插入图片描述

自动变量
Makefile 提供了几个自动变量,$^$@。使用这些自动变量可以使 Makefile 更加简洁。

  • $@:表示规则中的目标文件。在模式规则中,它特别有用,因为它代表了匹配模式的目标文件名。

  • $^:表示规则中的所有依赖文件(不包括重复的)。这是一个列表,包含了规则中所有的依赖项。

在这里插入图片描述


结尾

如果有什么建议和疑问,或是有什么错误,大家可以在评论区中提出。
希望大家以后也能和我一起进步!!🌹🌹
如果这篇文章对你有用的话,希望大家给一个三连支持一下!!🌹🌹

在这里插入图片描述

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

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

相关文章

【Java 基础】:三大特征之多态

✨ 杏花疏影里&#xff0c;吹笛到天明 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;java学习 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&…

JVM参数有哪些?

JVM调优主要是通过定制JVM参数来提Java应用程序的运行速度 JVM参数大致可以分为三类&#xff1a; &#xff11;、标准指令&#xff1a;&#xff0d;开头&#xff0c;这些是所有的HotSPot都支持的参数。可以用java -help打印出来&#xff1b; 2、非标准指令&#xff1a;-X开头…

Mysql高级篇(上)—— Mysql架构介绍(二)

Mysql高级篇&#xff08;上&#xff09; MySQL架构介绍&#xff08;二&#xff09;逻辑架构逻辑架构剖析MySQL8.0中SQL执行流程Linux环境下MySQL8.0中SQL执行原理MySQL语法顺序Oracle中SQL执行流程&#xff08;了解&#xff09;数据库缓存池 buffer pool&#xff08;了解&#…

86、pod部署策略

一、集群的调度 集群的调度&#xff1a; 怎么把pod部署到节点的方法。 1.1、调度的过程&#xff1a; scheduler是集群的调度器&#xff0c;主要任务就是把pod部署到节点上。 1.2、自动调度&#xff1a; 1、公平&#xff0c;保证每个可用的节点都可以部署pod 2、资源的高…

什么是工控安全,产线工控安全加固的方法

一、工控安全概述 想要了解工控安全&#xff0c;首先要了解其资产对象本身&#xff0c;也就是工业控制系统。 1、什么是工控 关于工业控制系统的定义&#xff0c;网上有很多&#xff0c;我就不再赘述&#xff0c;下面这张图是我从csdn找到的&#xff0c;个人觉得还不错。对照…

【多线程】CountDownLatch的简单实现

通过上一篇对CountDownLatch的使用&#xff0c;我们也明白了他的基本原理&#xff0c;接下来我们一起来实现一个CountDownLatch的基础效果 新建一个抽象类&#xff0c;包含countDownLatch需要的参数和方法 package com.atguigu.signcenter.nosafe.chouxiang;/*** author: jd* …

k8s集群的调度

目录 自动调度的原则 调度约束机制&#xff1a;list-watch apiserver和组件之间的watch机制 调度过程的默认算法 1.预算策略 预算的算法 2.优选策略 优选的算法 *用户定制节点部署 1.强制性节点部署 2.节点标签部署&#xff08;匹配机制&#xff09; 标签的增删改查…

selenium无法定位元素的几种解决方案

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、frame/iframe表单嵌套 WebDriver只能在一个页面上对元素识别与定位&#xff0c;对于frame/iframe表单内嵌的页面元素无法直接定位。 解决方法&#xff1a; d…

Hadoop 下载

下载法一&#xff1a;官方下载 hadoop官网 1.选择要下载的版本&#xff0c;这里我以3.4.0为例进行说明&#xff1b; 2.跳转后&#xff0c;选择对应系统架构的&#xff0c;进行下载&#xff1b; 下载法二&#xff1a;国内镜像源下载 1.阿里云 这里我以mac m1为案例&#x…

【已解决】Halcon错误代码4104

问题描述 在运行的时候发现报错4104&#xff0c;如下图所示 解决 从字面上理解就是超出了计算机的内存空间了&#xff0c;那么着手解决的话就需要把没次训练的张数减少一些即可。去相对应的修改batch_size即可。 结果 如下图所示&#xff0c;正常在使用GPU训练。 搞定&…

Xilinx FFT IP使用

简介 本章节主要介绍FFT原理,以及Xilinx的FFT IP使用说明做详细介绍。 FFT介绍 FFT主要是将时域信号转换成频域信号,转换后的信号更方便分析。首先,FFT是离散傅立叶变换 (DFT) 的快速算法,那么说到FFT,我们自然要先讲清楚傅立叶变换。先来看看傅立叶变换是从哪里来的? 傅…

虚拟机无法打开网卡 service network restart失败

问题描述 命令重启网卡服务&#xff0c;结果报错如下&#xff1a;Job for network.service failed because the control process exited with error code. See "systemctl status network.service" and "journalctl -xe" for details 根据提示&#xff…

Hi3061M开发板初测——点亮小灯

目录 前言环境配置点亮led源码IDA集成了串口监视器最后下载到开发板中运行 前言 海思MCU体验官活动&#xff0c;Hi3061M开发板到手后&#xff0c;配置环境初步测试点亮小灯。 环境配置 环境配置按照gitee提供的redeme一步一步来配置起来很顺利。具体可自行查阅&#xff1a;环境…

文件包含漏洞PHP伪协议利用方法

使用php伪协议的前提 php.ini中的allow_url_fopen 、allow_url_include这两个参数需要修改为on 1.file协议 使用file协议读取Windows的系统文件 http://127.0.0.1/123.php?cmdfile:///c:/windows/system32/drivers/etc/hosts 2.php://filter协议 使用php://filter协议可以…

JsonCpp库的使用

目录 一、Json数据格式 二、JsonCpp介绍 2.1 Json::Value 2.2 序列化接口 2.3 反序列化接口 三、JsonCpp的使用 3.1 头文件包含 3.2 序列化 3.3 反序列化 四、补充 Json 是⼀种数据交换格式&#xff0c;它采⽤完全独⽴于编程语⾔的⽂本格式来存储和表示数据。 一、J…

P01-Java何谓数组

P01-Java何谓数组 一、数组声明创建 1.1 数组声明的语法 与c有所不同 在Java中&#xff0c;数组声明语法 首选语法&#xff1a; //数据类型[] 数组名称; int[] arr;次选&#xff0c;与c类似 //数据类型 数组名称[]; int arr[];1.2 数组创建语法 与c指针有所相似&#xff0…

嵌入式开发与应用按键外部中断实验二

一、实验目的 1. 通过实验掌握中断式键盘控制与设计方法&#xff1b; 2. 熟悉编写中断服务程序; 3. 掌握中断系统相关知识&#xff0c;掌握外部中断应用方法和处理过程&#xff1b; 4. 掌握实验处理器中断处理的软件编程方法&#xff1b; 5. 从按键程序的设计对系统的编程…

Prometheus_0基础_学习笔记

一、基本概念 Prometheus是由golang语言开发的一套开源的监控、报警、时间序列数据库的组合&#xff0c;是一款基于时序数据库的开源监控告警系统。 时间序列数据库&#xff1a;时间序列数据库&#xff08;Time Serires Database , TSDB&#xff09;不同于传统的关系型数据库。…

是缔造AI程序员,还是AI缔造程序员?

随着AIGC&#xff08;如ChatGPT、MidJourney、Claude等&#xff09;大语言模型的涌现&#xff0c;AI辅助编程工具的普及使得程序员的工作方式正在发生深刻变革。AI的迅猛发展&#xff0c;不仅提升了编程效率&#xff0c;也引发了对程序员未来职业前景的深思。我们应当如何在这一…

【归并分而治之】逆序对的应对之策

目录 1.前言2.题目简介3.求解思路为什么要这样做&#xff1f;快在哪&#xff1f;为什么这种方法会想到结合归并排序&#xff1f;如何在一左一右中统计剩下的逆序对个数&#xff1f;固定右边的数&#xff0c;用降序会怎么样&#xff1f;&#xff1f;&#xff1f;思路的本质是巧妙…