当前位置: 首页 > news >正文

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

🔥 个人主页:大耳朵土土垚
🔥 所属专栏:Linux系统编程

这里将会不定期更新有关Linux的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉

文章目录

  • 前言
  • 1. 什么是make和Makefile?
  • 2. Makefile的基本结构
  • 3. Makefile的高级特性
  • 4. 使用make的优势
  • 5. 总结

前言

  在Linux及类Unix系统中,自动化构建项目是提高开发效率、减少重复劳动的关键环节。make工具及其配置文件Makefile是实现这一目标的重要工具组合。它们通过定义一系列规则和依赖关系,自动执行编译、链接等构建过程,确保软件项目能够高效、准确地构建。

1. 什么是make和Makefile?

  make 是一种控制程序生成的工具,它读取一个名为Makefile(或makefile,不区分大小写)的文件,并根据文件中的指令执行相应的命令。这些命令通常包括编译、链接等,用于生成最终的可执行文件或库文件。一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

  Makefile 是一个文本文件,其中包含了一系列的规则(rules)、目标(targets)、依赖(dependencies)和命令(commands)。每个规则定义了一个目标文件(通常是编译或链接的结果),以及生成该目标文件所需的依赖文件和要执行的命令。

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

  make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

2. Makefile的基本结构

  Makefile的基本结构由规则组成,每个规则通常包含以下部分:

  • 目标(target):通常是要生成的文件名,如可执行文件或对象文件。
  • 依赖(dependencies):生成目标所依赖的文件列表。
  • 命令(commands):生成目标需要执行的Shell命令,前面通常需要一个制表符(Tab)开头。

示例:

首先,这里有一个hello.c源文件:

hello.c的内容如下:

然后我们就可以通过创建一个Makefile文件来控制该代码生成程序(当然我们也可以直接使用gcc命令来生成可执行程序,但是随着源文件个数的增加,我们每次重新生成可执行程序时,所需输入的gcc指令的长度与个数也会随之增加,所以这时我们就需要使用make和Makefile了,这将大大减少我们的工作量),Makefile内容如下:

✨✨这里hello和clean就是我们的目标,hello.c就是要生成hello目标文件的依赖,而clean由.PHONY修饰,是一个伪目标,所以不需要依赖,伪目标的特性是,总是被执行的;gcc -o hello hello.crm -f hello 就是生成目标需要执行的Shell命令

然后我们就可以使用make来创建可执行程序hello:

在这个例子中,hello是最终的目标,它依赖于hello.c。为了生成hello,需要执行gcc -o hello hello.c命令,如上图绿色划线部分,这样我们直接使用make命令,它就可以帮我们在Makefile文件中找到生成hello的命令,自动执行。

此外在Makefile中clean是一个用.PHONY声明伪目标(不生成文件),用于清理构建过程中产生的文件,我们直接使用make clean指令即可删除对应的文件:

.PHONY:clean
clean:  rm -f hello 

可以看到之前make指令生成的可执行程序hello被删除了,其原因也是因为make clean命令使得它去Makefile文件中找到相关的指令rm -f hello进行删除

如果你想要删除多个文件,直接在rm -f 后面加文件名即可,例如我们可以将hello.c文件也删除:

结果如下:

可以看到已经没有hello和hello.c文件了

  • 我们发现使用clean命令时需要写make clean但是创建hello文件时只需要写make即可,这是因为如果只输入make命令,make会在当前目录下找名字叫“Makefile”或“makefile”的文件,如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“hello”这个文件,然后执行生成它的Shell命令,所以make后面的hello可以省略,只写一个make命令即可;
  • 如果找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错。

3. Makefile的高级特性

变量:Makefile中可以使用变量来存储文件名、编译器选项等,以提高灵活性和可维护性。
示例:

CC=gcc  
CFLAGS=-Wall -g  
hello: hello.o  $(CC) $(CFLAGS) -o hello hello.o

上述例子使用变量CC和CFLAGS来代替gcc和-Wall -g ,使用时需要使用括号并在前面加上$

自动变量:在规则中的命令里,可以使用一些特殊变量来表示依赖文件和目标文件等,如:

  • $@:表示依赖关系中的目标文件(冒号左侧)。
  • $^:表示依赖关系中的依赖文件列表(冒号右侧全部)。
  • $<:表示依赖关系中的第一个依赖文件(冒号右侧第一个)。

模式规则:允许为符合特定模式的文件指定构建规则,从而减少重复代码。
示例:

%.o: %.c  $(CC) $(CFLAGS) -c $< -o $@

条件判断:基于不同的条件执行不同的命令。
示例:

ifeq ($(OS),Windows_NT)  
CFLAGS += -DWIN32  
endif

函数:Makefile支持多种内置函数,用于处理文件名、字符串等。

4. 使用make的优势

  • 自动化:自动根据依赖关系执行必要的命令,减少手动操作。
  • 可维护性:通过清晰的规则和依赖关系,提高项目的可维护性。
  • 灵活性:支持变量、条件判断等高级特性,满足不同项目的构建需求。
  • 高效性:只重新构建已更改的部分,避免不必要的编译和链接。

5. 总结

  make和Makefile是Linux及类Unix系统中不可或缺的自动化构建工具。它们通过定义清晰的规则和依赖关系,极大地提高了软件项目的构建效率和可维护性。掌握make和Makefile的使用,对于开发者来说,是提升开发效率、保证项目质量的重要一步。

相关文章:

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

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…...

嵌入式开发中学习C++的用处?

这个问题一直有同学在问&#xff0c;其实从我的角度是一定是需要学的&#xff0c;最直接的就是你面试大厂的嵌入式岗位或者相关岗位&#xff0c;最后一定会问c&#xff0c;而很多人是不会的&#xff0c;这就是最大的用处&#xff0c;至于从技术角度考量倒是其次&#xff0c;因为…...

基于SAM大模型的遥感影像分割工具,用于创建交互式标注、识别地物的能力,可利用Flask进行封装作为Web后台服务

如有帮助&#xff0c;支持一下&#xff08;GitHub - Lvbta/ImageSegmentationTool-SAM: An interactive annotation case developed based on SAM for remote sensing image annotation, which can generate corresponding segmentation results based on point, multi-point, …...

Selenium入门

Selenium 是一个用于自动化 web 应用程序测试的工具&#xff0c;它支持多种浏览器和编程语言。 下载驱动程序&#xff1a;根据你的浏览器类型和版本&#xff0c;下载相应的 WebDriver。例如&#xff0c;Chrome 浏览器需要 ChromeDriver。 安装 Selenium 库 pip install sele…...

USB 3.1 Micro-A 与 Micro-B 插头,Micro-AB 与 Micro-B 插座,及其引脚定义

连接器配对 下表列出 USB 插座可接受的插头&#xff1a; USB 3.1 Micro-B 连接器 USB 3.1 Micro-B 插头和 USB 3.1 Micro-B 插座连接器是为小型手持设备和其他可能使用小尺寸连接器的应用而定义的。其定义使得 USB 3.1 Micro-B 插座既可以接受 USB 3.1 Micro-B 插头&#xff…...

MySQL多版本并发控制MVCC实现原理

MVCC MVCC 是多版本并发控制方法&#xff0c;用来解决读和写之间的冲突&#xff0c;比如脏读、不可重复读问题&#xff0c;MVCC主要针对读操作做限制&#xff0c;保证每次读取到的数据都是本次读取之前的已经提交事务所修改的。 概述 当一个事务要对数据库中的数据进行selec…...

【并查集】[ABC372E] K-th Largest Connected Components 题解

题意 前置阅读&#xff1a;并查集算法介绍 洛谷链接 Atcoder 链接 给定 n ( 1 ≤ n ≤ 2 1 0 5 ) n(1 \leq n \leq 2\times 10^5) n(1≤n≤2105) 个点&#xff0c;初始没有边&#xff0c;您要进行以下操作&#xff1a; 1 a b&#xff0c;表示连接一条 ( a , b ) (a,b) …...

HarmonyOS面试题(持续更新中)

1、用过线程通信吗&#xff0c;线程是怎么进行通信的&#xff1f; emitter 和 eventHub 相同&#xff1a; 都是基于事件总线的 区别是&#xff1a; ① eventHub当前线程内通信 ② emitter是同一进程不同线程或者同一进程和同一线程也可以通信 2、页面和组件的生命周期 …...

QT中QWidget和QObject的区别与联系是什么

在Qt框架中&#xff0c;QWidget和QObject是两个核心类&#xff0c;它们各自扮演着不同的角色&#xff0c;但又紧密相连。以下是关于它们区别与联系的详细解释&#xff1a; 区别 基类和功能定位&#xff1a; QObject是Qt中所有类的基类&#xff0c;包括几乎所有的Qt对象。它提供…...

解决macOS安装redis以后不支持远程链接的问题

参考文档:https://blog.csdn.net/qq_37703224/article/details/142542179?spm1001.2014.3001.5501 安装的时候有个提示, 使用指定配置启动: /opt/homebrew/opt/redis/bin/redis-server /opt/homebrew/etc/redis.conf那么我们可以尝试修改这个配置文件: code /opt/homebrew/…...

2024年研究生数学建模“华为杯”E题——肘部法则、k-means聚类、目标检测(python)、ARIMA、逻辑回归、混淆矩阵(附:目标检测代码)

文章目录 一、情况介绍二、思路情况二、代码展示三、感受 一、情况介绍 前几天也是参加了研究生数学建模竞赛&#xff08;也就是华为杯&#xff09;&#xff0c;也是和本校的两个数学学院的朋友在网上组的队伍。昨天&#xff08;9.25&#xff09;通宵干完论文&#xff08;一条…...

绝了,自从用了它,我每天能多摸鱼2小时!

大家好&#xff0c;我是可乐。 俗话说的好&#xff1a;“摸鱼一时爽&#xff0c;一直摸鱼一直爽”。 作为一个程序员&#xff0c;是否有过调试代码熬到深夜&#xff1f;是否有过找不到解决方案而挠秃头顶&#xff1f; 但现在你即将要解放了&#xff0c;用了这款工具——秘塔…...

C语言指针系列1——初识指针

祛魅&#xff1a;其实指针这块儿并不难&#xff0c;有人说难只是因为基础到进阶没有处理好&#xff0c;大家要好好跟着一步一步学习&#xff0c;今天我们先来认识一下指针 指针定义&#xff1a;指针就是内存地址&#xff0c;指针变量是用来存放内存地址的变量&#xff0c;在同一…...

传神论文中心|第26期人工智能领域论文推荐

在人工智能领域的快速发展中&#xff0c;我们不断看到令人振奋的技术进步和创新。近期&#xff0c;开放传神&#xff08;OpenCSG&#xff09;传神社区发现了一些值得关注的成就。传神社区本周也为对AI和大模型感兴趣的读者们提供了一些值得一读的研究工作的简要概述以及它们各自…...

NLP基础1

NLP基础1 深度学习中的NLP的特征输入 1.稠密编码&#xff08;特征嵌入&#xff09; 稠密编码&#xff08;Dense Encoding&#xff09;&#xff1a;指将离散或者高纬的稀疏数据转化为低纬度的连续、密集向量表示 特征嵌入&#xff08;Feature Embedding&#xff09; ​ 也称…...

001.docker30分钟速通版

docker简介 docker就是一个用于构建&#xff08;build&#xff09;&#xff0c;运行&#xff08;run&#xff09;&#xff0c;传送&#xff08;share&#xff09;应用程序的平台做一个不恰当的类比&#xff0c;就是外卖平台&#xff0c;如果你自己做华莱士不一定好吃&#xff0…...

Kafka 在 Linux 下的集群配置和安装

Kafka 在 Linux 下的集群配置和安装 Apache Kafka 是一个流行的分布式流处理平台&#xff0c;广泛用于实时数据管道和流处理应用。本文将详细讲解如何在 Linux 环境中配置和安装 Kafka 集群&#xff0c;并包括通过 Docker 安装和配置 Kafka 的步骤。每个步骤都将提供详细的解释…...

Python--操作列表

1.for循环 1.1 for循环的基本语法 for variable in iterable: # 执行循环体 # 这里可以是任何有效的Python代码块这里的variable是一个变量名&#xff0c;用于在每次循环迭代时临时存储iterable中的下一个元素。 iterable是一个可迭代对象&#xff0c;比如列表&#xff08;…...

JMeter(需要补充请在留言区发给我,谢谢)

一、学习工具 1、CinfigElement(HTTP Request Defaults、HTTP Header Manager、HTTP Authorization、CSV Data Set Config、User Defined Variables、JDBC Connection Configuration、HTTP Cookie Manager、Random Variable) 二、协议 1、HTTP协议&#xff08;消息体数据&am…...

线程池的执行流程和配置参数总结

一、线程池的执行流程总结 提交线程任务&#xff1b;如果线程池中存在空闲线程&#xff0c;则分配一个空闲线程给任务&#xff0c;执行线程任务&#xff1b;线程池中不存在空闲线程&#xff0c;则线程池会判断当前线程数是否超过核心线程数&#xff08;corePoolSize&#xff09…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...