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

图片名称
🎉博主首页: 有趣的中国人

🎉专栏首页: Linux

🎉其它专栏: C++初阶 | C++进阶 | 初阶数据结构

在这里插入图片描述

小伙伴们大家好,本片文章将会讲解Linux项目自动化构建工具make/makefile的相关内容。


如果看到最后您觉得这篇文章写得不错,有所收获,麻烦点赞👍、收藏🌟、留下评论📝。您的支持是我最大的动力,让我们一起努力,共同成长!

文章目录

  • 1. 何为make/makefile
  • 2. make/makefile的原理
  • 3. makefile中的变量以及自动显示问题
  • 4. makefile 目标文件的生成顺序



1. 何为make/makefile


当谈到在Linux中进行项目构建时,makemakefile是两个非常重要的工具。它们提供了一种自动化构建的方法,使得开发者能够轻松地编译和构建复杂的软件项目。下面我会分别介绍一下makemakefile


⏳ make 简介⌛

make 是一个命令行工具(指令),用于自动化构建程序或项目。它通过读取一个称为 makefile 的文件来确定构建项目所需的步骤。make工具的核心理念是根据文件之间的依赖关系以及每个文件的修改时间,决定哪些文件需要重新编译,从而实现高效的构建。


⏳ makefile 简介⌛

makefile 是一个文本文件,其中包含了一系列规则和命令,用于指导 make 工具如何构建项目。makefile 定义了项目中的各种组件(例如源文件、目标文件和依赖关系),以及如何将它们组合在一起以生成最终的可执行文件或库文件。



2. make/makefile的原理


⏳ 我们先来看一个例子:⌛

  1. 首先新建一个名为code.c的文件,并写入一段简单的代码:
# 新建名为code.c的文件 [dsj@alicloud-dsj lesson11]$ touch code.c  # code.c中所输入的代码#include <stdio.h> int main(){ 	 int i = 0; 	 for (i = 0;i < 10; ++i) 	 {printf("%d\n",i); 	} 	 return 0; } 
  1. 新建一个名为makefile或者Makefile的文件,并在其中输入以下代码:

在这里插入图片描述

code.exe:code.c 	gcc -o code.exe code.c.PHONY: clean clean: 	rm -f code.exe 

  1. 退出,并依次输入makemake clean指令:

输入make指令:

在这里插入图片描述

[dsj@alicloud-dsj lesson11]$ ll total 20
-rw-rw-r-- 1 dsj dsj  116 May  9 21:33 code.c
-rwxrwxr-x 1 dsj dsj 8360 May  9 21:38 code.exe
-rw-rw-r-- 1 dsj dsj   79 May  9 21:36 makefile 

输入make clean指令:
在这里插入图片描述

⏳ 原理解释⌛

看完之后我们可能对make/makefile有以下几点疑问:

1. makefile文件中的代码是什么意思;

2. 为什么输入make就能生成code.exe的文件,而不是 make code.exe


接下来我来一一解释这几个问题:


问题1:makefile文件中的代码是什么意思:

在这里插入图片描述
在这里插入图片描述

我们把code.exe 称为目标文件code.c称为依赖关系,下面的指令gcc -o code.exe code.c称为依赖方法

目标文件(targets)指定要构建的文件或操作的名称。这可以是可执行文件、目标文件、清理操作等。

依赖关系(Dependencies )指定每个目标所依赖的文件或操作。如果某个目标的依赖文件发生了变化,那么该目标就需要重新构建。有时,依赖关系可以省略依赖关系也可以有多个

依赖方法(Commands)指定 make 工具执行的操作步骤。这些操作通常是编译源代码、链接目标文件、复制文件等有时可以有多个依赖方法


这个搞明白了,那clean这个目标文件前面一行的.PHONY又是什么意思呢?


在这里插入图片描述


我们先了解一个概念:makefile中的操作默认是只执行一次的,因为这样可以提高编译的效率

.PHONY.PHONY 是告诉 make 工具,该目标不是实际的文件,而是一个动作或操作,并且这个操作总是要被执行的。

总是要执行的意思就是只要你输入了指令make clean这个指令那么对应的操作方法就要被执行。


那么问题又来了,只执行一次是怎么做到的呢?


  1. 首先我们可以用命令 stat [filename] 来查看一个文件的修改时间
  2. 其次,对于每个要生成的目标文件要依赖于依赖关系,而我们也可以查看这些依赖关系中的文件的修改时间,也可以查看目标文件的修改时间
  3. 如果 目标文件修改时间 先于 依赖文件的修改时间,说明依赖文件在编译后进行了修改,那么执行make指令,重新生成一个目标文件
  4. 反之,如果 目标文件修改时间 晚于 依赖文件的修改时间,说明依赖文件并没有进行修改,那么执行make指令 不会 重新生成一个目标文件

那我们来验证一下,看一下下面的例子吧:

目标文件 修改时间 晚于 依赖文件 修改时间的例子:

在这里插入图片描述

目标文件 修改时间 早于 依赖文件 修改时间的例子:

在这里插入图片描述


问题2: 为什么输入make就能生成code.exe的文件,而不是make code.exe


因为make指令会默认生成 makefile 中的第一个目标文件。但是输入make code.exe也是可以的。

在这里插入图片描述



3. makefile中的变量以及自动显示问题


makefile中我们可以用$@来代替目标文件$^来代替依赖关系文件,例如:

在这里插入图片描述

也是可以编译通过的😁!
在这里插入图片描述

makefile中也是可以出现变量的,但是这里的变量和其他编程语言有些不同,先看个例子吧:

注意定义变量的时候不能出现空格,除非依赖多个文件!
在这里插入图片描述
也是可以编译通过的😁!
在这里插入图片描述

我们发现在每次输入make指令的时候都会打印出他所执行的指令,例如:


在这里插入图片描述


我们可以修改相关的`makefile`代码,只需要在每个依赖方法之前加上`@`符号即可,使得它不出现:

不加@符号:

在这里插入图片描述


make一下会发现他把他所执行的指令和我们要让他打印的东西一起打印了:
在这里插入图片描述
@符号:

在这里插入图片描述

make一下会发现他并没有把他所需要执行的指令打印出来,只打印了我们让他打印的东西:
在这里插入图片描述



4. makefile 目标文件的生成顺序


看一下这个makefile文件:

在这里插入图片描述

源码:

code.exe: code.sgcc -o $@ $^
code.o: code.sgcc -o $@ -c $^
code.s: code.igcc -o $@ -S $^
code.i: code.cgcc -o $@ -E $^.PHONY:clean
clean:rm -f code.i code.s code.o code.exe

如果我们直接make,由于找不到依赖文件code.s,但是此时不会停止执行,会继续向下寻找,但是向下找到了code.o文件,但是它的依赖文件是code.s文件,因为此时没有code.c文件,会继续向下寻找……
可以发现,这类似于递归的一个过程,没找到就会继续递归,直到找到为止。
当然如果最后还是找不到需要的依赖文件就会报错。

报错示例:

在这里插入图片描述

在这里插入图片描述

🤔当然,由于make指令默认生成的是第一个目标文件,所以指挥生成和第一个目标文件相关的内容,我们可以改一下顺序来验证一下,咱们将.o放在第一个:


在这里插入图片描述

在这里插入图片描述

🤔那如果咱们再改一下顺序,把.o需要的.s文件不放在直接顺序上的下一个会怎么样呢?


在这里插入图片描述

🤔可以发现还是可以的,不会报错。


在这里插入图片描述


🐼所以说,只要makefile文件中给出了所需要的依赖文件,make都能帮你找到,不会报错🎋

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

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

相关文章

2024年自动驾驶、车辆工程与智能交通国际会议(ICADVEIT2024)

2024年自动驾驶、车辆工程与智能交通国际会议&#xff08;ICADVEIT2024&#xff09; 会议简介 2024年自动驾驶、车辆工程和智能交通国际会议&#xff08;ICADVEIT 2024&#xff09;将在中国深圳举行。会议主要聚焦自动驾驶、车辆工程和智能交通等研究领域&#xff0c;旨在为从…

盲盒一番赏小程序:探索未知,开启神秘宝藏之旅

开启神秘之门&#xff0c;探索未知的乐趣 在繁忙的生活中&#xff0c;我们渴望一丝丝未知带来的惊喜与乐趣。盲盒一番赏小程序&#xff0c;正是为了满足您这种探索未知的欲望而诞生。它不仅仅是一个购物平台&#xff0c;更是一个充满神秘与惊喜的宝藏世界。 精选好物&#xf…

Electron学习笔记(一)

文章目录 相关笔记笔记说明 一、轻松入门 1、搭建开发环境2、创建窗口界面3、调试主进程 二、主进程和渲染进程1、进程互访2、渲染进程访问主进程类型3、渲染进程访问主进程自定义内容4、渲染进程向主进程发送消息5、主进程向渲染进程发送消息6、多个窗口的渲染进程接收主进程发…

Linux:进程信号

生活角度的信号 a.信号在生活中&#xff0c;随时可以产生(信号的产生和我是异步的) b.你能认识这个信号 c.我们知道信号产生了&#xff0c;我能识别这个信号&#xff0c;信号该怎么处理 d.我们可能正在做着更重要的事情&#xff0c;把到来的信号暂不处理(1.我记得这个事 2.…

YOLOv9中模块总结补充|RepNCSPELAN4详图

专栏地址&#xff1a;目前售价售价69.9&#xff0c;改进点70 专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;助力高效涨点&#xff01;&#xff01;&#xff01; 1. RepNCSPELAN4详图 RepNCSPELAN4是YOLOv9中的特征提取-融合模块&#xff0c;类似前几…

phpstudy(MySQL启动又立马停止)问题的解决办法

方法一&#xff1a;查看本地安装的MySQL有没有启动 1.鼠标右击开始按钮选择计算机管理 2.点击服务和应用程序 3.找到服务双击 4.找到MySQL服务 5.双击查看是否启动&#xff0c;如启动则停止他&#xff0c;然后确定&#xff0c;重新打开phpstudy,启动Mysql. 方法二&#xff…

Python从0到POC编写--实用小脚本02

爆破脚本&#xff1a; 爆破脚本也是我们经常使用的东西 这里就简单讲讲后台爆破脚本的编写吧 在编写之前&#xff0c;我们先通过访问网站去看看情况 首先我们可以先登录看看 输入账号 admin &#xff0c;密码 12345 后 登录失败&#xff0c;提示 用户名或密码错误 在输入…

苹果新品发布会速览:iPad革新遇市场挑战 | 百能云芯

北京时间5月7日晚&#xff0c;苹果以“放飞吧”为主题&#xff0c;举办了一场不到40分钟的线上新品发布会。在这场发布会上&#xff0c;iPad产品线成为了焦点&#xff0c;M4芯片和OLED技术的融入更是引起了广泛关注。 iPad新篇章&#xff1a;技术革新与市场竞争 时隔18个月&…

WebSocket 多屏同显和异显

介绍 多屏同显:通过在一个应用上进行操作之后,另一个应用也能跟着一起发生改变,例如app1播放了晴天这首音乐,那么app2也要同步播放这首音乐,确保所有屏幕显示的内容完全相同。多屏异显:每个屏幕可以显示不同的内容,或者在内容更新时存在一定的延迟,而不需要严格保持同步…

Linux下的SPI通信

SPI通信 一. 1.SPI简介: SPI 是一种高速,全双工,同步串行总线。 SPI 有主从俩种模式通常由一个主设备和一个或者多个从设备组从。SPI不支持多主机。 SPI通信至少需要四根线,分别是 MISO(主设备数据输入,从设备输出),MOSI (主设数据输出从设备输入),SCLK(时钟信号),CS/SS…

物理层——计算机网络学习笔记二

目录 物理层的基本概念 数据通信的基础知识 物理层下面的传输媒体 信道复用技术 图片大部分来源于谢希仁《计算机网络》教材配套的ppt。 这一样都是介绍一下概念性的东西&#xff0c;了解一下就行&#xff0c;就重要性而言不如后面的内容。 物理层的作用&#xff1a;考虑如何才…

android基础-服务

同样使用intent来传递服务 oncreate是服务第一次启动调用&#xff0c;onStartCommand是服务每次启动的时候调用&#xff0c;也就是说服务只要启动后就不会调用oncreate方法了。可以在myservice中的任何位置调用stopself方法让服务停止下来。 服务生命周期 前台服务类似于通知会…

在Linux操作系统中扩建swap容量

在Linux操作系统上创建硬盘分区不仅可以储存数据&#xff0c;还可以使用创建的硬盘分区去扩展机器上swap分区的大小——去扩展交换工具的容量。 有些软件对于swap分区的大小是有要求的&#xff0c;swap分区的大小小于多少就安装不上软件。 要扩展swap容量要么重装系统&#x…

初学者理解Transformer,本文is all you need

要问现在AI领域哪个概念最热&#xff0c;必然是openAI推出chatGPT之后引发的大模型。然而这项技术的起源&#xff0c;都来自一篇google公司员工的神作“Attention Is All You Need”——本文标题也是一种致敬^_^&#xff0c;目前已有近12万的引用(还在增长)。 在“Attention Is…

【教程】极简Python接入免费语音识别API

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;请不吝给个[点赞、收藏、关注]哦~ 安装库&#xff1a; pip install SpeechRecognition 使用方法&#xff1a; import speech_recognition as srr sr.Recognizer() harvard sr…

C++:哈希表和unordered系列容器的封装

一、unordered系列关联式容器的介绍 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可达到log2N&#xff0c;即最差情况下需要比较红黑树的高度次&#xff0c;当树中的节点非常多时&#xff0c;查询效率也不理想。最好的查询是&…

索引失效情况

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;面经 ⛺️稳中求进&#xff0c;晒太阳 一、索引列上运算操作。 不要在索引列上进行运算操作&#xff0c;否则索引会失效。 在tb_user的phone列加上索引&#xff0c;然后进行条件查询&am…

Kafka从0到消费者开发

安装ZK Index of /zookeeper/zookeeper-3.9.2 下载安装包 一定要下载-bin的&#xff0c;不带bin的是源码&#xff0c;没有编译的&#xff0c;无法执行。-bin的才可以执行。 解压 tar -zxvf apache-zookeeper-3.9.2-bin.tar.gz 备份配置 cp zoo_sample.cfg zoo_sample.cfg-b…

调用 gradio 创建聊天网页报错(使用远程服务器)

文章目录 写在前面1、使用默认IP地址&#xff08;失败&#xff09;2、使用本地IP地址&#xff08;失败&#xff09;3、使用远程服务器IP地址&#xff08;成功&#xff09; 写在前面 我复现了github上的 llama-chinese 的工作 使用的是 llama2&#xff0c;环境配置是在远程服务…

指针的奥秘(二):指针与数组的联系+字符指针+二级指针+指针数组+《剑指offer》笔试题

指针 一.指针与数组的联系1.数组名的理解2.使用指针访问数组3.一维数组传参的本质 二.字符指针1.字符指针隐藏秘密2.常量字符串3.《剑指offer》笔试题 三.二级指针四.指针数组1.指针数组模拟二维数组 一.指针与数组的联系 1.数组名的理解 也许大部分人认为数组名就是一个名称&…